Skip to content

Add basic SpotLight instancing#249

Open
JezSonic wants to merge 7 commits into
mainfrom
dev/e3d-model-lights
Open

Add basic SpotLight instancing#249
JezSonic wants to merge 7 commits into
mainfrom
dev/e3d-model-lights

Conversation

@JezSonic
Copy link
Copy Markdown
Member

Fixes #134

@JezSonic JezSonic self-assigned this May 12, 2026
@JezSonic JezSonic force-pushed the dev/e3d-model-lights branch from 50396df to a712969 Compare May 12, 2026 20:32
@JezSonic JezSonic requested a review from marcinn May 12, 2026 20:33
@JezSonic JezSonic force-pushed the dev/e3d-model-lights branch from a712969 to 79bf9a6 Compare May 12, 2026 20:39
if parent == null:
return
var light_root = parent.get_parent()
var is_end = parent.name.begins_with("end")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this parent-child relation and hardcoded names of related nodes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me neither, but that's the best I could come up with. Also _end is a part of their standard naming of light-related nodes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I think that e3d_light contains logic which should be moved to e3d instancing or e3d parsing stage.
  2. MaSzyna quirks like matching something by part of a node name should be configurable. Please note that node name in Godot can be different than e3d (sub)model name.
  3. E3D Light in this implementation will be always a spotlight. You never be able to create omni lights or other lights. That's why it is better to move nodes creation to the factories like e3d nodes instancer.
  4. At the e3d parsing stage you can traverse e3d model tree to find parent-child relationships between submodels, if needed.
  5. Try to store references between e3d submodels in thei, i.e. add properties similar to nodepath (you can't use nodepath though, but a reference to other node should work)

func _ready():
_update_state()

func _update_state():
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the high level API for lights control should be on E3DModelInstance, which is a node proxy for instancer and a reference holder for a e3d model.

Optimised instancer will not use this node. It will control lights by calling RenderingServer directly.

for light in lights:
var base_name = light.name.to_lower()

var on_suffixes = ["_on", "_xon"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instancer should work with a structure resolved by parser. E3dmodel should have references to light nodes. We shouldn't implement e3d quirks here like finding node by specific name


E3DSubModel.SubModelType.SUBMODEL_FREE_SPOTLIGHT:
obj = SpotLight3D.new()
obj.set_script(preload("res://addons/libmaszyna/e3d/e3d_light.gd"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was generated by AI, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I don't understand why we're using set_script and preloading instead of classes like MyCustomClass.new()

Comment thread doc_classes/E3DSubModel.xml Outdated
<member name="light_range" type="float" setter="set_light_range" getter="get_light_range" default="0.0">
The maximum range of the light source.
</member>
<member name="near_atten_start" type="float" setter="set_near_atten_start" getter="get_near_atten_start" default="0.0">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use full names instead of shortcuts

@marcinn
Copy link
Copy Markdown
Member

marcinn commented May 12, 2026

It's almost fine. I would like to move lights controller to e3dmodelinstance, which will delegate lights handling to a selected instancer. E3DSpotlight node is probably unnecessary.

I think the code is partially AI assisted. Please clean the code before next review (inconsistent naming, preloading scripts inside the logic code, using set_script etc)

Copy link
Copy Markdown
Member

@marcinn marcinn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stil, I think that references to lights / array of lights should be implemented at the resource layer (e3dmodel/e3dsubmodel). Instancer should only fetch the lights and apply transforms if needed.

Also there should be a kind of high level API for toggling lights - E3DModelInstance should be a good place, because it is a connector between e3d model and instancer. E3DModelInstance should delegate light control to instancer, same as instantiating and cleaning up.

This PR is not handling texture based lights. We can split this, of course, but thinking about submodels with emissive materials as lights (instead of spotlights) should be helpful for designing the lights api.


E3DSubModel.SubModelType.SUBMODEL_FREE_SPOTLIGHT:
obj = SpotLight3D.new()
obj.set_script(preload("res://addons/libmaszyna/e3d/e3d_light.gd"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I don't understand why we're using set_script and preloading instead of classes like MyCustomClass.new()

if parent == null:
return
var light_root = parent.get_parent()
var is_end = parent.name.begins_with("end")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I think that e3d_light contains logic which should be moved to e3d instancing or e3d parsing stage.
  2. MaSzyna quirks like matching something by part of a node name should be configurable. Please note that node name in Godot can be different than e3d (sub)model name.
  3. E3D Light in this implementation will be always a spotlight. You never be able to create omni lights or other lights. That's why it is better to move nodes creation to the factories like e3d nodes instancer.
  4. At the e3d parsing stage you can traverse e3d model tree to find parent-child relationships between submodels, if needed.
  5. Try to store references between e3d submodels in thei, i.e. add properties similar to nodepath (you can't use nodepath though, but a reference to other node should work)

if not child:
continue

if child.has_method("_update_state"):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a property which identifies the light. you're assuming here that any object with "_update_state" is a light.

if child is Node3D and submodel.transform:
var child_node:Node3D = child as Node3D
child_node.transform = submodel.transform
if child is SpotLight3D:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code assumes that there is only one type of light - a SpotLight3D, not even E3DLight. Checking E3DSubModel.SubModelType.SUBMODEL_FREE_SPOTLIGHT will be consistent with _create_submodel_instance() impl.

@JezSonic JezSonic force-pushed the dev/e3d-model-lights branch 5 times, most recently from f863cac to b197cc2 Compare May 24, 2026 21:28
@JezSonic JezSonic changed the title Add basic SopotLight instancing Add basic SpotLight instancing May 24, 2026
@marcinn marcinn force-pushed the dev/e3d-model-lights branch from 193e997 to 175af9e Compare May 25, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add instancing of SpotLight3D nodes

2 participants