[Solved] Adding child to an existing element to inherits it’s lights

Hi,



I use an imported model via OgreXML as battleground for my game.

Once the battleground is loaded ( and updated ), I add some characters on it.

My characters are also imported via OgreXML but they don’t have their own lights.



For now, I add a simple sunlight to my rootNode to see my characters.



My problem is as follow : I want the characters to inherits the lights from the battleground.





I use this method in the actual system to add my characters :



[java]

private void addSceneCharacterToTeam( SceneCharacter sceneChar, SceneTeam team )

{

// Add physics node

PhysicsCharacterNode node = sceneChar.getPhysicNode();

characterNodes.add( node );



rootNode.attachChild( node );

physicsSpace.add( node );

[…]

}

[/java]



So I tried to change it to :

[java]

private void addSceneCharacterToTeam( SceneCharacter sceneChar, SceneTeam team )

{

// Add physics node

PhysicsCharacterNode node = sceneChar.getPhysicNode();

characterNodes.add( node );



Node parent = (Node) battlegroundNode;

parent.updateGeometricState();

parent.attachChild( node );

parent.updateGeometricState();



physicsSpace.add( node );

[…]

}

[/java]



But it doesn’t behave as I wanted :frowning:

  • The character position is messed up. ( I think its something to do with my battleground center not in the origin. I should be able to manage this point )
  • The character doesn’t inherit the lights of the parent node. ( They are invisible if I don’t add a SunLight )
  • I have some error when I try to cast a collision ray though one of them :

    [java]

    java.lang.IllegalStateException: Scene graph must be updated before checking collision

    at com.jme3.scene.Geometry.collideWith(Geometry.java:225)

    at com.jme3.scene.Node.collideWith(Node.java:498)

    [/java]



    I also tried to use :

    [java]

    battlegroundNode.getLocalLightList();

    battlegroundNode.getWorldLightList();

    [/java]

    but it seems that the lists are empty.



    I think I have miss something somewhere but … I don’t know what xD

    If someome can give me a hint …



    Thanks in advance !

It depends on where the lights are placed in the scene. If your scene is lit, that means the light should be on the root, so you should see something there

Hi,

In fact, I do not wish to add lights to the root node via code in an explicit manner.

I wish to define my lights directly inside my 3D Editor. ( When I create my battleScene )



For example, I have a battleScene that is a small house.









I wish to be able to add some lights via my 3D editor without having to edit the JAVA part.

For that, I see two options :

  • Detecting the lights when adding my .j3o and transfert them to the root node.
  • Add the character as subchilds of the child battleSceme and let them herit the lights of their parent.



    I’m stuck on my two options xD



    PS : Perhaps the problem resides when I add the battleScene. This is not something I’m experienced at, so their may be some options I don’t know when adding the models.

    [java]

    private void createBattlegroundModel( String fileName, float width, float depth )

    {

    //Create 3D model

    battlegroundModel = ViewManager.getAssetManager().loadModel( fileName );



    //

//Scale
//
BoundingBox box = ((BoundingBox)battlegroundModel.getWorldBound());

float currentWidth = box.getXExtent();
float currentDepth = box.getZExtent();

//Scale
float scaleX = width / ( currentWidth * 2 );
float scaleZ = depth / ( currentDepth * 2 );
float scaleY = ( scaleX + scaleZ ) / 2 ;
battlegroundModel.scale( scaleX, scaleY, scaleZ );

battlegroundModel.setLocalTranslation( 0, 0, 0 );
}
[/java]


Edit :
I have also spotted where my point lights are declared inside my XML.
Perhaps the problems come from them :
[java]
<node name="FireLight">
<position x="-17.4648" y="-0.400392" z="-4.05256" />
<scale x="1" y="1" z="1" />
<rotation qx="-0.707107" qy="-0" qz="-0" qw="-0.707107" />
<light name="FireLight" visible="true" type="point" castShadows="false" power="0.1">
<colourDiffuse r="1.02652" g="0.7215" b="0.243195" />
<colourSpecular r="1" g="1" b="1" />
<lightAttenuation range="10000" constant="1" linear="0" quadric="0" />
</light>
</node>
<node name="ExteriorLight">
<position x="34.0681" y="2.44519" z="8.73039" />
<scale x="1" y="1" z="1" />
<rotation qx="-0.707107" qy="-0" qz="-0" qw="-0.707107" />
<light name="ExteriorLight" visible="true" type="point" castShadows="false" power="0.266667">
<colourDiffuse r="0.948811" g="0.910556" b="1.03358" />
<colourSpecular r="1" g="1" b="1" />
<lightAttenuation range="10000" constant="1" linear="0" quadric="0" />
</light>
</node>
[/java]

Would this work?

[java]

final Node rootNode = …



scene.breadthFirstTraversal(new SceneGraphVisitor(){

public void visit(Spatial spatial){

for (Light l : spatial.getLocalLightList()){

rootNode.addLight(l);

}

spatial.getLocalLightList().clear();

}

});



[/java]

Edit : It works !!! I had done a mistake in my procedure getWorldLightList() → getLocalLightList();

Thanks a lot !





Hmmm…

Is the SceneGraph advisor one of your custom classes ( I didn’t find it inside source library.0

Well, my library that dates from 31-12-2010… I should do an update soon xD

( I didn’t find breadthFirstTraversal either )



So I tried to adapt your code to my use :


[java]

moveBattleGroundsLights( battlegroundNode );

[…]

private void moveBattleGroundsLights( Spatial spatial )

{

for( Iterator<Light> i = spatial.getWorldLightList().iterator(); i.hasNext(); )

{

Light thisLight = i.next();

System.out.println( "Add a light of type " + thisLight.getType().toString() );

rootNode.addLight(thisLight);

this.light = thisLight;

}

spatial.getLocalLightList().clear();



try {

Node node = (Node) spatial;

for( int i = 0; i < node.getChildren().size(); i++ )

{

Spatial child = node.getChild( i );

System.out.println( “Loop on : " + child.getName() );

moveBattleGroundsLights( child );

}

}

catch( Exception e )

{

LogManager.debug( this, spatial.getName() + " cannot be converted into a node” );

}



}

[/java]

I’m visiting all the nodes but… each one seems to have two lights

→ My battleScene became pitch white xD


[java]

Loop on : a0K_ArnanStart_main-scene_node

Add a light of type Point

Add a light of type Point

Loop on : House-node

Add a light of type Point

Add a light of type Point

Loop on : House-entity

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_House-ogremesh

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_House-geom-1

Add a light of type Point

Add a light of type Point

Loop on : Ground-node

Add a light of type Point

Add a light of type Point

Loop on : Ground-entity

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Ground-ogremesh

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Ground-geom-2

Add a light of type Point

Add a light of type Point

Loop on : Table-node

Add a light of type Point

Add a light of type Point

Loop on : Table-entity

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Table-ogremesh

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Table-geom-3

Add a light of type Point

Add a light of type Point

Loop on : Lader-node

Add a light of type Point

Add a light of type Point

Loop on : Lader-entity

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Lader-ogremesh

Add a light of type Point

Add a light of type Point

Loop on : a0K_ArnanStart_Lader-geom-4

Add a light of type Point

Add a light of type Point

Loop on : FireLight-node

Add a light of type Point

Add a light of type Point

Loop on : ExteriorLight-node

Add a light of type Point

Add a light of type Point

[/java]