dDrive - little car driving game

@zzuegg said: If i would have to guess, glow filter, custom shader that takes a boolean for each light (on/off) and a texture where the alpha channel is used to index the lights.

Thank you for your answer :).
I’m sorry, I’m an idiot, you see :D… what means “to index the lights”?

@dawnmichal said: Shaders are one big mystery for me :D So I used maybe less effective way. But it's simple. I have two materials. First only with diffuse map and second with diffuse and glow map (https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:bloom_and_glow). Then I only change material when light is on.

Thank you for your answer :).
Hehe ok, good simple solution :D. Does it mean you have one glow texture per combination of lights?

I know nothing about shaders either, but I think imma gonna try zzuegg’s (once I understand it :D) way because I would have different models roaming around and want to save on memory and stuff.

Concerning the debug translation… are you using bullet in parallel mode? Think it says in the doc that such troubles may happen then.

What i ment is something quite simple… lets assume you have 10 lights on the car, then you can use the alpha channel for indexing lights.
alpha=0.1->light1
alpha=0.2->light2
and so on…

then in the fragment shader of the glow technique you could have something like


if(light1==true){
  vec4 textureColor = texture(...)

  if(textureColor.a==0.1){  //make sure to ceil/floor first
    fragColor=vec4(textureColor.rgb,1);

  }else{
    fragColor=vec4(0,0,0,1);

  }
}

with a bit more thinking it should be possible without branching too.

But yeah, i would be curious too if you have a a different glow texture for each combination of light…

@loopies said: Thank you for your answer :). Hehe ok, good simple solution :D. Does it mean you have one glow texture per combination of lights?

I have only two materials for all vehicle lights. All lights are unwrapped with theirs UV mapping coordinates and I have two textures (DIFFUSE and GLOW). All lights are independent geometric objects so I assign specific material for each light depends on it’s state (on/off). So I don’t have glow texture for all light on/off combinations :wink:

@loopies said: Concerning the debug translation... are you using bullet in parallel mode? Think it says in the doc that such troubles may happen then.

I’m using SEQUENTIAL ThreadingType. But THX for tip.

@Ascaria said: show (ukaž) us (nám) your (tvůj) way (způsob) of creating (vytváření) an world (světa) :) ( :) )

There are some fragmets… World is just for testing. I have mainly worked on vehicles so far.

GameState initialize:

super.initialize(stateManager, app);
this.app = (SimpleApplication) app;

localRootNode = new Node("GameState RootNode");
this.app.getRootNode().attachChild(localRootNode);

bulletAppState = new BulletAppState();
this.app.getStateManager().attach(bulletAppState);
bulletAppState.getPhysicsSpace().enableDebug(getAssetManager());

player = new Player(this, getPhysicsSpace());
localRootNode.attachChild(player.getRootNode());

Material matFloor = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
matFloor.setBoolean("UseMaterialColors", true);
matFloor.setColor("Diffuse", ColorRGBA.LightGray);
matFloor.setColor("Ambient", ColorRGBA.Gray);
//matFloor.getAdditionalRenderState().setWireframe(true);
        
Material matObstacles = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
matObstacles.setBoolean("UseMaterialColors", true);
matObstacles.setColor("Diffuse", ColorRGBA.Red);
matObstacles.setColor("Ambient", ColorRGBA.Gray);
//matObstacles.getAdditionalRenderState().setWireframe(true);
      
Node levelNode = (Node)getAssetManager().loadModel("Maps/park.j3o");
levelNode.setLocalTranslation(0, 0, 0);
localRootNode.attachChild(levelNode);
        
Geometry myGeometry = (Geometry)levelNode.getChild("Ground1");
myGeometry.setShadowMode(ShadowMode.Receive);
myGeometry.setMaterial(matFloor);
     
myGeometry = (Geometry)levelNode.getChild("Wall1");
myGeometry.setShadowMode(ShadowMode.CastAndReceive);
myGeometry.setMaterial(matObstacles);
        
myGeometry = (Geometry)levelNode.getChild("Obstacle11");
myGeometry.setShadowMode(ShadowMode.CastAndReceive);
myGeometry.setMaterial(matObstacles);
        
myGeometry = (Geometry)levelNode.getChild("Obstacle21");
myGeometry.setShadowMode(ShadowMode.CastAndReceive);
myGeometry.setMaterial(matObstacles);
        
myGeometry = (Geometry)levelNode.getChild("Obstacle31");
myGeometry.setShadowMode(ShadowMode.CastAndReceive);
myGeometry.setMaterial(matObstacles);
       
myGeometry = (Geometry)levelNode.getChild("Obstacle41");
myGeometry.setShadowMode(ShadowMode.CastAndReceive);
myGeometry.setMaterial(matObstacles);
        
RigidBodyControl worldControl = new RigidBodyControl(0);
worldControl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
worldControl.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01);
levelNode.addControl(worldControl);
getPhysicsSpace().add(worldControl);

Player class constructor

public Player(GameState gameState, PhysicsSpace space) {
        this.gameState = gameState;
        
        Material playerMat = new Material(gameState.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        playerMat.setBoolean("UseMaterialColors", true);
        playerMat.setColor("Diffuse", ColorRGBA.Gray);
        playerMat.setColor("Ambient", ColorRGBA.Gray);
        //carMat.getAdditionalRenderState().setWireframe(true);
                
        playerNode = (Node)this.gameState.getAssetManager().loadModel("Models/Characters/human.j3o");
        playerNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        playerNode.setMaterial(playerMat);
        
        playerControl = new BetterPlayerControl(0.3f, 1.8f, 80, this);
        playerNode.addControl(playerControl);
        
        playerControl.setJumpForce(new Vector3f(0,400f,0)); 
        playerControl.setGravity(new Vector3f(0,1f,0));
        //playerControl.warp(new Vector3f(0,0,0));
        
        space.add(playerControl);
        
        initSound("Player/walk_cement.wav", true);
        initSound("Player/run_cement.wav", true);
        initSound("Player/jump_up_cement.wav", false);
        initSound("Player/jump_down_cement.wav", false);
    }

Thank you (dikec) :slight_smile: ( :slight_smile: )

@dawnmichal said: GameState initialize: Player class constructor

hmm this looks fine, but i dont see collision shape creation anywhere
hmm tohle vypada v poradku, akorat vubec nikde nevidim kde se k tomu svetu tvori collision shape.

anyway, it looks like, after world is created, you moved it by some offset, but you dont updated physics, like:
v kazdym pripade to vypada, jako kdybys po nacteni vseho ten svet pak nejak posunul o nejaky kus aniz bys upravil fyziku
neco jako:


Node world = assetManager.load(worldPath);
world.addControl(new RigidBodyControl(CollisionShapeFactory.createMeshShape(world), 0));
world.getChild(0).setLocalTranslation(-20f, -20f, -20f);

or you can maybe used
nebo si taky mohl treba pouzit


CollisionShapeFactory.shiftCompoundShapeContents(CompoundCollisionShape compoundShape, Vector3f vector);

otherwise i dont know
jinak si to neumim vysvetlit

@ - MichalDawn: oh ok one geometry per light. Yup, simple and easy.
I’m still going to try zzuegg’s solution for 3 reasons:

  • I need to get into shaders to add some visual fun to my tubes
  • 8 vehicles * 7 lights = 56 more objects. 84 if I got up to 12 vehicles. I haf special needs :D.
  • seems easier to work on the glow texture than to position those objects (once the shader has been done and I’m 2 years into the future haha).

This being said, it’s good to know there’s a tested fall back plan if I’m too obtuse for the shader solution. Thank you!

@ - zzuegg thanks for that info and snippet. Will help tremendously.

@dawnmichal said: Ok.... I have weird problem with physics debug. When I enable debug by space.enableDebug() method I realise that physics world seems to be shifted compared to 3D rendered world (see screenshot). All objects are shifted. Some tips? It must be some noob beginner mistake, but I can't figure it out...

This has happened to me before, I searched for a while until I discovered I needed to leave the geometry local translation at {0,0,0} and then setPhysicsLocation() where I actually wanted the geometry to appear. This way, they’re matching the same world space coordinates. If you set the local translation and then add the control, it might do what’s happening to you.

In other words, make sure your node/geometries are not translated at all before you add the RigidBodyControl control to it, else the rendered geometry will be displaced from its RigidBodyControl (which is also a useful feature in some particular cases, at least I use it so that some geometries look intersected. This couldn’t be the case if the geomtries were always matching the RigidBodyControl, since 2 rigid bodies can’t cross together.)

@Ascaria said: hmm this looks fine, but i dont see collision shape creation anywhere

It’s done in BetterPlayerControl constructor.

    public BetterPlayerControl(float radius, float height, float mass, Player player) {
        super(radius, height, mass);
        
        this.player = player;
        this.radius = radius;
        this.height = height;
        this.mass = mass;
        rigidBody = new PhysicsRigidBody(getShape(), mass);
        rigidBody.setAngularFactor(0);
    }
@.Ben. said: In other words, make sure your node/geometries are not translated at all before you add the RigidBodyControl control to it, else the rendered geometry will be displaced from its RigidBodyControl.......

I check it and we will see :wink:

@dawnmichal said: I check it and we will see ;)

Try something similar to this:

[java]
Node car = new Node(“Dat Car”);
car.addControl(new RigidBodyControl()); // Whatever mass you want, etc…
rootNode.attachChild(car);
getPhysicsSpace().add(car);
car.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(10,10,10));
// Do not use setLocalTranslation() before or even after, instead use: car.getControl(RigidBodyControl.class).setPhysicsLocation() …
[/java]

The setPhysicsLocation() will take care of translating the geometry as well. They will both always match perfectly.

@.Ben. said: In other words, make sure your node/geometries are not translated at all before you add the RigidBodyControl control to it

damn why i didnt think about this? :slight_smile:

note: setting localTranslation is fine before you attach rigidbody control to it, but look after spatial.isApplyPhysicsLocal()
https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/bullet-common/com/jme3/bullet/control/RigidBodyControl.java#118
after that, you should move only with that rigid body :slight_smile:

To me, it’s not about “it’s not fine” but it displaces the control from the center of the spatial, so if you want them to match, you have to make sure they have both the same center (origin).

@.Ben. said: To me, it's not about "it's not fine" but it displaces the control from the center of the spatial, so if you want them to match, you have to make sure they have both the same center (origin).

yea i have strong difficulties, when i have my model separated in 3ds max (like hull, left wing, right wing) but every part is in its place. i can play with origin… when i import obj into jme3, every geometry is perfectly in its place this is ok, but when i create collision shape using CollisionShapeFactory.createBoxCompoundShape() all its collisionshape parts are at 0,0,0 and not where geometries really are, origin is lost

this is last hint: when you create model in 3d editor, make sure, it is oriented about 3d editor’s 0,0,0 regardles origin.

I do not know how CompoundShape works exactly, but if creating the collision shape combines all objects into one, it’s quite understandable the 3 objects origins will be lost because they’re combined, so it probably creates a new collision shape and that shape has a new origin of zero. Maybe you can try to make 3 distinct collision shapes instead of combining them? If this is important that it stays as a compound shape then why not displace each part’s physics control to back where they were? Put their translation into a Vector3f variable and then do the compound shape creation and then apply a setPhysicsLocation() on each part back to where they were before, that’s it?

I solve this! :smiley: It was a (maybe) beginner’s mistake.
I had this property in my new Calendar class:
private Vector3f sunVector = Vector3f.ZERO;
and then in update method:
sunVector.set(x, y, z);

So Vector3f.ZERO can’t be changed like this:
Vector3f.ZERO = new Vector3f(1,1,1);
but can be changed like this:
Vector3f.ZERO.set(1,1,1);
… and Vector3f.ZERO becomes not zero :wink:

That confuse me, because this isn’t possible in C#. e.g. this won’t work:
Brushes.AliceBlue.Color = Color.FromRgb(0, 0, 0);

I started to use (and learn) Java along with JME. So bear with me :wink:
But thank you for your interest and tips.

@dawnmichal said: Vector3f.ZERO.set(1,1,1); ... and Vector3f.ZERO becomes not zero ;)

Well… that explains a lot then! But why would you do that? I mean why not just do instead: new Vector3f(1,1,1) ?

I did not do it intentionally. It was an accident.
I stored Vector3f.ZERO reference to Calendar property called sunVector. Then I changed sunVector property using SET method and forgot that there is the Vector3f.ZERO object reference. This would not happen in C#.

I understand it was not intentional, but I want to understand the motivation to store Vector3f.ZERO which is supposed to be used as a constant more or less (I call it a modal), but did you know if you want to copy a Vector3f and store it, you could just do like this instead: Vector3f my_stored_independant_copy = Vector3f.ZERO.clone();

This way, whatever you do afterwards won’t affect the modal.

lol it happened to me also, that i changed vector3f.zero :smiley: golden rule is, you can use it, you should never change it

also:


// very very wrong (i did it too :) )
private Vector3f sunVector = Vector3f.ZERO;
// correct 
private Vector3f sunVector = Vector3f.ZERO.clone();
// best
private Vector3f sunVector = new Vector3f();

after this lesson, i learned to use “new Vector3f()” :slight_smile:

also #2:
it is good practise to do things like this

public void setBla(Vector3f ble) {
    bla.set(ble);
}

dont be afraid to create a bunch of vector3f instances, just make sure to create 1 instance for 1 thing and modify it by for example like this:
vector.set(otherVector).multLocal(5f)
but not this:
vector.set(otherVector.mult(5f))
vector.set(otherVector.multLocal(5f))

edit #3:
in c# that vector3f would probably be struct, not class, so “class with behavior like integer”

Both of you are absolutely right. Valuable experience :smiley:

@.Ben. said: but I want to understand the motivation to store Vector3f.ZERO....

I forgot .clone() :slight_smile:

I’m trying to solve my shadow issue, which I mentioned in previous posts.
I tried to use setFlushQueues as pspeed suggested. Things changed. Now I have shadows but with wierd black areas behind spot light. See picture:

Shadow Error

I have simple scene with park model and two lights. First DirectionalLight (yelow arrow shows light direction) with DirectionalLightShadowFilter. Second SpotLight (blue dot shows the position and direction is obvious from light cone) with SpotLightShadowFilter. Objects in front of SpotLight casts good shadows, but what about black spots (marked in green “ellipse” :smiley: ) behind SpotLight? These black spots are moving with SpotLight. It looks like some inverted SpotLight shadows…

I created simple mygame application only with simpleInitApp method:

        this.cam.setLocation(new Vector3f(0,10,0));
        getFlyByCamera().setMoveSpeed(20);
                
        Box b = new Box(0.5f, 0.5f, 0.5f);
        Geometry geom = new Geometry("Box", b);
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom.setMaterial(mat);
        rootNode.attachChild(geom);
        geom.setLocalTranslation(new Vector3f(0,2,0));
        
        Material matFloor = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        matFloor.setBoolean("UseMaterialColors", true);
        matFloor.setColor("Diffuse", ColorRGBA.LightGray);
        matFloor.setColor("Ambient", ColorRGBA.Gray);
        Material matObstacles = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        matObstacles.setBoolean("UseMaterialColors", true);
        matObstacles.setColor("Diffuse", ColorRGBA.Red);
        matObstacles.setColor("Ambient", ColorRGBA.Gray);

        Node levelNode = (Node)getAssetManager().loadModel("Models/park.j3o");
        rootNode.attachChild(levelNode);
        Geometry myGeometry = (Geometry)levelNode.getChild("Ground1");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.Receive);
        myGeometry.setMaterial(matFloor);
        myGeometry = (Geometry)levelNode.getChild("Wall1");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        myGeometry.setMaterial(matObstacles);
        myGeometry = (Geometry)levelNode.getChild("Obstacle11");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        myGeometry.setMaterial(matObstacles);
        myGeometry = (Geometry)levelNode.getChild("Obstacle21");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        myGeometry.setMaterial(matObstacles);
        myGeometry = (Geometry)levelNode.getChild("Obstacle31");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        myGeometry.setMaterial(matObstacles);
        myGeometry = (Geometry)levelNode.getChild("Obstacle41");
        myGeometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        myGeometry.setMaterial(matObstacles);
   
        FilterPostProcessor filterPostProcesor = new FilterPostProcessor(getAssetManager());
        getViewPort().addProcessor(filterPostProcesor);
        
        DirectionalLight dLight = new DirectionalLight();
        dLight.setDirection(new Vector3f(1, -1, -1));
        rootNode.addLight(dLight);
        
        SpotLight sLight = new SpotLight();
        sLight.setSpotRange(200);
        sLight.setSpotInnerAngle(15 * FastMath.DEG_TO_RAD);
        sLight.setSpotOuterAngle(35 * FastMath.DEG_TO_RAD);
        sLight.setColor(ColorRGBA.White.mult(1.3f));
        sLight.setPosition(new Vector3f(0,2,0));
        sLight.setDirection(new Vector3f(0,0,1));
        rootNode.addLight(sLight);
        
        final int SHADOWMAP_SIZE=4096;
        DirectionalLightShadowFilter dShadow = new DirectionalLightShadowFilter(getAssetManager(), SHADOWMAP_SIZE, 3);
        dShadow.setLight(dLight);
        dShadow.setEnabled(true);
        dShadow.setShadowIntensity(0.7f);
        dShadow.setShadowCompareMode(CompareMode.Hardware);
        dShadow.setEdgeFilteringMode(EdgeFilteringMode.PCF8);
        dShadow.setEnabledStabilization(true);
        dShadow.setEdgesThickness(1);
        dShadow.setFlushQueues(false);
         
        SpotLightShadowFilter sShadow = new SpotLightShadowFilter(getAssetManager(), SHADOWMAP_SIZE);
        sShadow.setLight(sLight);
        sShadow.setEnabled(true);
        sShadow.setShadowIntensity(0.7f);
        sShadow.setShadowCompareMode(CompareMode.Hardware);
        sShadow.setEdgeFilteringMode(EdgeFilteringMode.PCF8);
        sShadow.setEdgesThickness(1);
        sShadow.setFlushQueues(true);
        
        filterPostProcesor.addFilter(dShadow);
        filterPostProcesor.addFilter(sShadow);

Thank you.

Hi all.
new update here :slight_smile: Shadow issue still is still unsolved, but I also worked on other things.

  • The configuration file now can control the vehicle model animation. This allows me to realize animated interior like speedometer, tachometer, steering wheel and handbrake. In the future there will be more animated objects.
  • The individual vehicle parts may be interactive, depending on the vehicle configuration file. So far I have only implemented the handbrake, but again I plan to add more interactive parts and objects.
  • I started working on the model of the vehicle interior. There are no textures, only basic 3D model.
  • I improved vehicle lights and modified daily cycle.

Here is a new video:
YouTube

2 Likes