Skip to content

Commit

Permalink
add godot state and hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
lokimckay committed May 13, 2024
1 parent f7ca1be commit 3ce51b1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_dispatch:
push:
paths:
- "addons/godot-rapier-3d/rust/**"
- "addons/godot-rapier-3d/**"
tags:
- "v[0-9]+.[0-9]+.[0-9]+" # Regex for a version number such as v0.2.1

Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ It is _not_ a drop-in replacement for the Godot physics engine. Rapier nodes ope

1. Download the [latest release](https://github.com/deltasiege/godot-rapier-3d/releases/latest)
1. Extract the release archive into your godot project's root directory
1. If your Godot project is already open, you may get console errors. These can be safely ignored by starting your game or reloading your project
1. If your Godot project is already open, you may get console errors. These can be safely ignored by reloading your project
1. Add RapierRigidBody3D nodes to your scene and some RapierCollider3D + MeshInstance3D nodes as children of the rigid bodies
1. Run your game

Your physics objects should simulate! 🎉

## Configuring

By default, the `Rapier3DDebugger` autoload will start the physics simulation for you. To get more control over when you simulate, search for `Rapier 3D` in your project settings and disable either `Run in Game` or `Show UI` under the Debug category.
By default, the `Rapier3DDebugger` autoload will start the physics simulation for you. To get more control over when you simulate, search for `Rapier 3D` in your project settings and disable either `Debug in Game` or `Show UI` under the Debug category.

Now you can call `Rapier3D.step()` from within any `_physics_process()` function, or as often as you like. This function advances the physics simulation by 1 step.

Expand Down Expand Up @@ -91,11 +91,16 @@ See [CONTRIBUTING.md](CONTRIBUTING.md)

## Attributions

- [gdext](https://github.com/godot-rust/gdext) discord community
- [Lili Zoey](https://github.com/lilizoey)
- [Bromeon](https://github.com/Bromeon)
- [dsnopek](https://github.com/dsnopek) and [SGPhysics2D](https://www.snopekgames.com/tutorial/2021/getting-started-sg-physics-2d-and-deterministic-physics-godot)
- [GameDevelopmentCenter](https://www.youtube.com/c/GameDevelopmentCenter)
- [appsinacup/godot-rapier-2](https://github.com/appsinacup/godot-rapier-2d)
- [ilyas-taouaou/rapier-gdext](https://github.com/ilyas-taouaou/rapier-gdext)

Thanks very much for your help

[rapier-link]: https://rapier.rs/
[godot-link]: https://godotengine.org/
[gdext-link]: https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/what_is_gdextension.html
10 changes: 10 additions & 0 deletions addons/godot-rapier-3d/Rapier3D.gd
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
extends Node3D

const utils = preload("res://addons/godot-rapier-3d/gdscript/utils.gd")
const physics_state = preload("res://addons/godot-rapier-3d/gdscript/physics_state.gd")

signal physics_ready

func _physics_process(_delta):
Expand All @@ -17,3 +20,10 @@ func set_state(physics_state: PackedByteArray):

func get_hash(physics_state: PackedByteArray) -> int:
return Array(physics_state.compress()).hash()

func get_godot_state() -> PackedByteArray:
var ret = physics_state._get_physics_state(get_tree().current_scene)
return ret

func get_godot_hash(physics_state: PackedByteArray) -> int:
return Array(physics_state.compress()).hash()
13 changes: 9 additions & 4 deletions addons/godot-rapier-3d/gdscript/physics_controls.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ var play = false
var should_show = false
var initial_snapshot
var snapshot
var snapshot_hash
var rapier_hash
var godot_hash

@onready var hash_label = $SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer/Hash
@onready var rapier_hash_label = $SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer/RapierHash
@onready var godot_hash_label = $SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer/GodotHash
@onready var play_button = $SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer/PlayButton
@onready var canvas = $SubViewport/CanvasLayer

Expand All @@ -27,8 +29,11 @@ func _physics_process(_delta):

func _save() -> PackedByteArray:
var snap = Rapier3D.get_state()
snapshot_hash = Rapier3D.get_hash(snap)
hash_label.text = "Hash: " + str(snapshot_hash)
var godot_snap = Rapier3D.get_godot_state()
rapier_hash = Rapier3D.get_hash(snap)
godot_hash = Rapier3D.get_godot_hash(godot_snap)
rapier_hash_label.text = "Rapier hash: " + str(rapier_hash)
godot_hash_label.text = "Godot hash: " + str(godot_hash)
return snap

func _load(snap):
Expand Down
8 changes: 6 additions & 2 deletions addons/godot-rapier-3d/gdscript/physics_controls.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ layout_mode = 2
layout_mode = 2
text = "Godot Rapier 3D"

[node name="Hash" type="Label" parent="SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer"]
[node name="RapierHash" type="Label" parent="SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer"]
layout_mode = 2
text = "Hash: "
text = "Rapier hash: "

[node name="GodotHash" type="Label" parent="SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer"]
layout_mode = 2
text = "Godot hash: "

[node name="PlayButton" type="CheckButton" parent="SubViewport/CanvasLayer/Panel/MarginContainer/GridContainer"]
layout_mode = 2
Expand Down
31 changes: 31 additions & 0 deletions addons/godot-rapier-3d/gdscript/physics_state.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const utils = preload("res://addons/godot-rapier-3d/gdscript/utils.gd")

static func _get_physics_state(root: Node3D):
var state = PackedByteArray()
var physics_objects = _get_all_physics_objects(root)
var sorted = _sort_by_iid(physics_objects)
for obj: Node3D in physics_objects:
var pos = obj.global_transform.origin
var bsis = obj.global_transform.basis
state.append_array(var_to_bytes(pos))
state.append_array(var_to_bytes(bsis))
return state

static func _get_all_physics_objects(root: Node3D) -> Array[Node3D]:
var physics_objects: Array[Node3D] = []
utils._append_children_by_class("RapierRigidBody3D", root, physics_objects)
utils._append_children_by_class("RapierCollider3D", root, physics_objects)
return physics_objects

static func _sort_by_iid(nodes: Array[Node3D]):
var arr = nodes.duplicate(true)
arr.sort_custom(_compare_iid)
return arr

#Returns true if B has greater instance id than A
static func _compare_iid(a, b):
if a.get_instance_id() < b.get_instance_id(): return true
return false

static func _check_sort(nodes: Array[Node3D]):
for node in nodes: print("IID: ", node.get_instance_id())
6 changes: 3 additions & 3 deletions addons/godot-rapier-3d/gdscript/utils.gd
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#static func _append_children_with_class(_class: String, node: Node, arr: Array):
#if node.is_class(_class): arr.append(node)
#for child in node.get_children(): _append_children_with_class(_class, child, arr)
static func _append_children_by_class(_class: String, node: Node, arr: Array):
if node.is_class(_class): arr.append(node)
for child in node.get_children(): _append_children_by_class(_class, child, arr)
4 changes: 4 additions & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ config/icon="res://assets/gr3d-logo.svg"
Rapier3D="*res://addons/godot-rapier-3d/Rapier3D.gd"
Rapier3DDebugger="*res://addons/godot-rapier-3d/Rapier3DDebugger.gd"

[debug]

rapier_3d/show_ui=false

[editor_plugins]

enabled=PackedStringArray()

0 comments on commit 3ce51b1

Please sign in to comment.