Godot Version
4.2.2
Question
I actived the space, added body to the space but it still doesn’t move.
Both entity and body the preset added doesn’t work.
Sorry for a lot of code.
My code:
preset/test.gd
extends Preset
static var logger = Log.register_logger("*_Preset_Test_LogSource")
class Tracker extends Node:
var phyrid: RID
func _physics_process(_delta: float) -> void:
print(PhysicsServer3D.body_get_state(phyrid, PhysicsServer3D.BODY_STATE_TRANSFORM))
var directional_light: RID
var instance: RID
var instance2: RID
var body: RID
var shape: RID
var mesh = BoxMesh.new()
func _data() -> void:
super._data()
id = "test"
func _assign() -> void:
Vars.presets.register_preset_group("*").add(self)
func _show_description(node: ScrollContainer) -> void:
var label = Label.new()
label.text = tr("*_Presets_Test_Description")
node.add_child(label)
func _pre_config_preset() -> bool:
return true
func _init_preset() -> void:
var world = Vars.worlds.create_world()
var entity = TestEntity.TYPE.create(false)
world.add_child_entity(entity)
entity.object_create()
entity = Hidden_Entity_Test.TYPE.create(false)
entity.transform = Transform3D(Basis.IDENTITY, Vector3(0, 8, 0))
world.add_child_entity(entity)
entity.object_create()
func _after_ready() -> void:
directional_light = RenderingServer.directional_light_create()
RenderingServer.light_set_color(directional_light, Color.WHITE)
RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_ENERGY, 1)
RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_INDIRECT_ENERGY, 1)
RenderingServer.light_set_param(directional_light, RenderingServer.LIGHT_PARAM_RANGE, 100)
instance = RenderingServer.instance_create()
RenderingServer.instance_set_base(instance, directional_light)
RenderingServer.instance_set_transform(instance, Transform3D.IDENTITY.rotated(Vector3.RIGHT, -PI / 6).rotated(Vector3.UP, PI / 6))
RenderingServer.instance_set_scenario(instance, Vars.worlds.worlds[1].scenario)
# mesh.size = Vector3(100, 2, 100)
PhysicsServer3D.area_set_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY, 9.8)
PhysicsServer3D.area_set_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR, Vector3.DOWN)
logger.debug("Setup gravity: %s for %s" % [PhysicsServer3D.area_get_param(Vars.worlds.worlds[1].space, PhysicsServer3D.AREA_PARAM_GRAVITY), Vars.worlds.worlds[1].space])
shape = PhysicsServer3D.box_shape_create()
PhysicsServer3D.shape_set_data(shape, Vector3(1, 1, 1))
logger.debug("Created shape: %s" % str(shape))
body = PhysicsServer3D.body_create()
PhysicsServer3D.body_add_shape(body, shape, Transform3D.IDENTITY, 1)
PhysicsServer3D.body_set_state(body, PhysicsServer3D.BODY_STATE_TRANSFORM, Transform3D.IDENTITY.translated(Vector3(0, -5, 0)))
PhysicsServer3D.body_set_mode(body, PhysicsServer3D.BODY_MODE_RIGID)
logger.debug("Created body: %s" % str(body))
PhysicsServer3D.body_set_space(body, Vars.worlds.worlds[1].space)
logger.debug("Attached body: %s to space: %s" % [body, Vars.worlds.worlds[1].space])
print(PhysicsServer3D.space_is_active(Vars.worlds.worlds[1].space))
var tracker = Tracker.new()
tracker.phyrid = body
Vars.add_child(tracker)
Vars.worlds.worlds[1].toggle_to.call_deferred()
# instance2 = RenderingServer.instance_create()
# RenderingServer.instance_set_base(instance2, mesh.get_rid())
# RenderingServer.instance_set_transform(instance, Transform3D.IDENTITY \
# .translated(Vector3.DOWN * 0.2))
# RenderingServer.instance_set_scenario(instance2, Vars.worlds.worlds[1].scenario)
func _apply_preset() -> void:
pass
func _enable_preset() -> void:
pass
func _disable_preset() -> void:
RenderingServer.free_rid(directional_light)
RenderingServer.free_rid(instance)
RenderingServer.free_rid(instance2)
func _load_preset_data(_stream: Stream) -> Error:
return OK
func _save_preset_data(_stream: Stream) -> void:
pass
entities/test.gd
class_name Hidden_Entity_Test
extends StandalonePhysicsEntity
static func get_type() -> ObjectType:
return (Gindustry_Entity_Test as Object).get_meta(OBJECT_TYPE_META)
var shape_rid: RID
var shape: int
var box: BoxMesh
var instance: RID
func _object_init() -> void:
super._object_init()
shape_rid = PhysicsServer3D.box_shape_create()
PhysicsServer3D.shape_set_data(shape_rid, Vector3(1, 1, 1))
shape = add_shape(shape_rid, Transform3D.IDENTITY, 1)
box = BoxMesh.new()
box.size = Vector3(1, 1, 1)
box.material = StandardMaterial3D.new()
box.material.albedo_color = Color(1, 0, 0)
instance = RenderingServer.instance_create()
RenderingServer.instance_set_base(instance, box.get_rid())
PhysicsServer3D.body_set_mode(physics_body_rid, PhysicsServer3D.BODY_MODE_RIGID)
func _object_free() -> void:
PhysicsServer3D.free_rid(shape_rid)
RenderingServer.free_rid(instance)
super._object_free()
func _entity_init() -> void:
super._entity_init()
RenderingServer.instance_set_scenario(instance, world.scenario)
func _entity_deinit() -> void:
super._entity_deinit()
func _load_data(stream: Stream) -> Error:
var err = super._load_data(stream)
if err: return err
return Utils.load_data_with_version(stream, [])
func _save_data(stream: Stream) -> void:
super._save_data(stream)
Utils.save_data_with_version(stream, [])
func _on_transform_changed(source: Entity) -> void:
super._on_transform_changed(source)
RenderingServer.instance_set_transform(instance, get_global_transform())
world.gd
class_name World
extends Entity
static var logger: Log.Logger
const TILE_SIZE = 0.25
const TILE_SIZE_VECTOR = Vector3.ONE * TILE_SIZE
static func get_type() -> ObjectType:
return (World as Object).get_meta(OBJECT_TYPE_META)
var is_root_world: bool = false;
var scenario: RID:
get: return parent_entity.scenario if parent_entity and parent_entity != self else scenario
set(v): scenario = v;
var space: RID:
get: return parent_entity.space if parent_entity and parent_entity != self else space
set(v): space = v;
var camera: RID:
get: return parent_entity.camera if parent_entity and parent_entity != self else camera
set(v): camera = v
var chunks: Dictionary = {} # Vector3i -> Chunk
static func create() -> World:
return TYPE.create();
func _object_create() -> void:
super._object_create()
if not logger:
logger = Log.register_logger("World_LogSource")
func _object_init() -> void:
super._object_init()
Vars.worlds.worlds[object_id] = self
if is_root_world:
self.world = self
scenario = RenderingServer.scenario_create()
logger.debug("Scenario created: %s" % str(scenario))
space = PhysicsServer3D.space_create()
logger.debug("Space created: %s" % str(space))
camera = RenderingServer.camera_create()
RenderingServer.camera_set_cull_mask(camera, 1)
RenderingServer.camera_set_transform(camera, Transform3D.IDENTITY)
func _object_ready() -> void:
if object_ready: return
super._object_ready()
if is_root_world:
PhysicsServer3D.space_set_active(space, true)
logger.debug("Space active: %s" % str(space))
func _object_free() -> void:
if is_root_world:
if Vars.worlds.current_toggled_world == self:
RenderingServer.viewport_set_scenario(get_viewport().get_viewport_rid(), RID())
RenderingServer.viewport_attach_camera(get_viewport().get_viewport_rid(), RID())
Vars.worlds.current_toggled_world = null
PhysicsServer3D.free_rid(space)
RenderingServer.free_rid(camera)
RenderingServer.free_rid(scenario)
super._object_free()
func toggle_to() -> void:
if not object_ready: return
if Vars.worlds.current_toggled_world == root_world: return
Vars.worlds.current_toggled_world = root_world
var viewport = get_viewport()
RenderingServer.viewport_set_scenario(viewport.get_viewport_rid(), root_world.scenario)
RenderingServer.viewport_attach_camera(viewport.get_viewport_rid(), root_world.camera)
func _load_data(stream: Stream) -> Error:
super._load_data(stream)
return Utils.load_data_with_version(stream, [func():
is_root_world = stream.get_8() == 1;
if stream.get_error(): return stream.get_error()
return OK
])
func _save_data(stream: Stream) -> void:
super._save_data(stream)
Utils.save_data_with_version(stream, [func():
stream.store_8(1 if is_root_world else 0);
])
physics_entity.gd
class_name PhysicsEntity
extends Entity
signal shape_data_changed(shapeidx: int)
static func get_type() -> ObjectType:
return (PhysicsEntity as Object).get_meta(OBJECT_TYPE_META)
func _get_physics_body_rid() -> RID:
return RID()
func get_physics_body_rid() -> RID:
return _get_physics_body_rid()
func get_parent_standalone_physics_entity() -> StandalonePhysicsEntity:
var curr = self
while curr:
if curr is StandalonePhysicsEntity:
return curr
curr = curr.parent_entity
return null
var shape_inc_idx: int = 1
var shapes: Dictionary = {}
var shape_transforms: Dictionary = {}
var shape_attached_idxs: Dictionary = {}
var shape_masses: Dictionary = {}
func __attach_shape(shapeidx: int) -> void:
PhysicsServer3D.body_add_shape(get_physics_body_rid(), \
shapes[shapeidx], Transform3D.IDENTITY)
shape_attached_idxs[shapeidx] = PhysicsServer3D.body_get_shape_count(get_physics_body_rid()) - 1
__update_shape(shapeidx)
func __update_shape(shapeidx: int) -> void:
var parent = get_parent_standalone_physics_entity()
var shape_local = get_relative_transform(parent).affine_inverse() * shape_transforms[shapeidx]
PhysicsServer3D.body_set_shape_transform(get_physics_body_rid(), \
shape_attached_idxs[shapeidx], shape_local)
shape_data_changed.emit(shapeidx)
parent.physics_child_shape_changed(self)
func __detach_shape(shapeidx: int) -> void:
PhysicsServer3D.body_remove_shape(get_physics_body_rid(), shape_attached_idxs[shapeidx])
var idx = shape_attached_idxs[shapeidx]
shape_attached_idxs.erase(shapeidx)
for sidx in shape_attached_idxs:
if shape_attached_idxs[sidx] > idx:
shape_attached_idxs[sidx] -= 1
func add_shape(shape: RID, shape_transform: Transform3D, mass: float = 0) -> int:
var idx = shape_inc_idx
shapes[idx] = shape
shape_transforms[idx] = shape_transform
shape_masses[idx] = mass
if entity_active:
__attach_shape(idx)
shape_inc_idx += 1
return idx
func set_shape_transform(shapeidx: int, shape_transform: Transform3D) -> void:
shape_transforms[shapeidx] = shape_transform
if entity_active and shape_attached_idxs.has(shapeidx):
__update_shape(shapeidx)
func set_shape_mass(shapeidx: int, mass: float) -> void:
shape_masses[shapeidx] = mass
if entity_active and shape_attached_idxs.has(shapeidx):
__update_shape(shapeidx)
func remove_shape(shapeidx: int) -> void:
if not shapes.has(shapeidx): return
if entity_active:
__detach_shape(shapeidx)
shapes.erase(shapeidx)
shape_transforms.erase(shapeidx)
shape_attached_idxs.erase(shapeidx)
func has_shape(shapeidx: int) -> bool:
return shapes.has(shapeidx)
func _entity_init() -> void:
super._entity_init()
for shapeidx in shapes:
__attach_shape(shapeidx)
func _entity_deinit() -> void:
for shapeidx in shapes:
__detach_shape(shapeidx)
super._entity_deinit()
standalone_physics_entity.gd
class_name StandalonePhysicsEntity
extends PhysicsEntity
static var logger = Log.register_logger("StandalonePhysicsEntity_LogSource")
static func get_type() -> ObjectType:
return (StandalonePhysicsEntity as Object).get_meta(OBJECT_TYPE_META)
var physics_body_rid: RID
var physics_child_entities: Array[PartialPhysicsEntity]
var in_physics_transform_sync: bool = false
var physics_last_transform: Transform3D
func _object_init() -> void:
super._object_init()
physics_body_rid = PhysicsServer3D.body_create()
PhysicsServer3D.body_attach_object_instance_id(physics_body_rid, get_instance_id())
func _get_physics_body_rid() -> RID:
return physics_body_rid
func _object_free() -> void:
if physics_body_rid:
PhysicsServer3D.free_rid(physics_body_rid)
physics_body_rid = RID()
super._object_free()
func _entity_init() -> void:
super._entity_init()
__update_physics()
PhysicsServer3D.body_set_space(physics_body_rid, world.space)
logger.debug("Set space: %s for %s" % [world.space, physics_body_rid])
PhysicsServer3D.body_apply_force(physics_body_rid, Vector3.UP * 100, Vector3.ZERO)
func _entity_deinit() -> void:
PhysicsServer3D.body_set_space(physics_body_rid, RID())
logger.debug("Unset space: %s" % str(physics_body_rid))
super._entity_deinit()
func _physics_process(_delta: float) -> void:
if not entity_active: return
var rid = get_physics_body_rid()
if not rid.is_valid(): return
var new_transform = PhysicsServer3D.body_get_state(rid, PhysicsServer3D.BODY_STATE_TRANSFORM)
physics_transform_changed(new_transform)
func physics_transform_changed(new_transform: Transform3D) -> void:
if physics_last_transform.is_equal_approx(new_transform): return
physics_last_transform = new_transform
in_physics_transform_sync = true
new_transform = parent_entity.get_global_transform().affine_inverse() * new_transform
transform = new_transform
in_physics_transform_sync = false
func _on_transform_changed(source: Entity) -> void:
super._on_transform_changed(source)
if in_physics_transform_sync: return
if source is StandalonePhysicsEntity and source != self:
var rid = get_physics_body_rid()
var new_transform = PhysicsServer3D.body_get_state(rid, PhysicsServer3D.BODY_STATE_TRANSFORM)
physics_transform_changed(new_transform)
return
var global_transform = get_global_transform()
PhysicsServer3D.body_set_state(physics_body_rid, PhysicsServer3D.BODY_STATE_TRANSFORM, \
global_transform)
physics_last_transform = global_transform
func add_physics_child(child: PartialPhysicsEntity) -> void:
physics_child_entities.append(child)
if entity_active: __update_physics()
func remove_physics_child(child: PartialPhysicsEntity) -> void:
physics_child_entities.erase(child)
if entity_active: __update_physics()
func physics_child_shape_changed(_child: PhysicsEntity) -> void:
__update_physics()
func __update_physics() -> void:
var centroid_sum = Vector3()
var mass = 0
for shapeidx in shape_attached_idxs:
var origin = shape_transforms[shapeidx].origin
origin = get_relative_transform(self).affine_inverse() * origin
var shape_mass = shape_masses[shapeidx]
centroid_sum += origin * shape_mass
mass += shape_mass
for child in physics_child_entities:
for shapeidx in child.shape_attached_idxs:
var origin = child.shape_transforms[shapeidx].origin
origin = child.get_relative_transform(self).affine_inverse() * origin
var shape_mass = child.shape_masses[shapeidx]
centroid_sum += origin * shape_mass
mass += shape_mass
PhysicsServer3D.body_set_param(physics_body_rid, PhysicsServer3D.BODY_PARAM_CENTER_OF_MASS, \
centroid_sum / mass)
PhysicsServer3D.body_set_param(physics_body_rid, PhysicsServer3D.BODY_PARAM_MASS, mass)
Output:
...
[Main_LogSource] [LogLevel_Info] Main_StateChanged Core_State_MAIN_MENU Core_State_PRESET_CONFIG
[Game_LogSource] [LogLevel_Info] Game_LoadStarted
[Main_LogSource] [LogLevel_Info] Main_StateChanged Core_State_PRESET_CONFIG Core_State_LOADING_GAME
[World_LogSource] [LogLevel_Debug] Scenario created: RID(10548439678977)
[World_LogSource] [LogLevel_Debug] Space created: RID(10638633992192)
[Game_LogSource] [LogLevel_Info] Game_Ready
[World_LogSource] [LogLevel_Debug] Space active: RID(10638633992192)
[StandalonePhysicsEntity_LogSource] [LogLevel_Debug] Set space: RID(10638633992192) for RID(10758893076481)
[Game_LogSource] [LogLevel_Info] Game_Enter
[Main_LogSource] [LogLevel_Info] Main_StateChanged Core_State_LOADING_GAME Core_State_IN_GAME
[*_Preset_Test_LogSource] [LogLevel_Debug] Setup gravity: 9.80000019073486 for RID(10638633992192)
[*_Preset_Test_LogSource] [LogLevel_Debug] Created shape: RID(11265699217409)
[*_Preset_Test_LogSource] [LogLevel_Debug] Created body: RID(11338713661442)
[*_Preset_Test_LogSource] [LogLevel_Debug] Attached body: RID(11338713661442) to space: RID(10638633992192)
true
(268) [X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, -5, 0)]