All scaled models

Is their a way to scale models of varying parameters to a specific set so that if a model is modeled to small or to big when imported into jme they can all have the same proportions?

Core-Dump said:

can't you simply use fixed scale values, instead of computing them somehow?


I actually do want to do fixed scale values however the initial approach was to make a more general loader. In other words the way I currently have everything set up is that depending if its scaled properly a box will be smaller than a character.

The issue is that models are of varying sizes and I want to be able to directly control their size

for example using the models from the repo and the code below the robots are much smaller than the ninjas is thier a fix for the code i'm using below i can use


private void scale(Node theNode){
                 //in which ize.Average.getObjectSize() returns a static vector of values
      theNode.setLocalScale(size.Average.getObjectSize());   
      theNode.setModelBound(new BoundingBox());
      theNode.updateModelBound();
      theNode.updateGeometricState(0, true);
      theNode.updateWorldBound();
   }

I know their must be an obvious way i'm over looking but i can't tell is their anyway to prevent that because sometimes they spawn extremely big as well probably only have the size scaled

yes there is.



import the model,

add a BoundingBox,

update the BoundingVolume,

read Proportions of the boundingbox,

-> when your desired maximum x proportion is N then, and for y … and z, call:


model.setLocalScale(N / bb.xExtent, N / bb.yExtent, N / bb.zExtent);


update the GeometricState and add to the rootNode.

there you go
dhdd said:

yes there is.

import the model,
add a BoundingBox,
update the BoundingVolume,
read Proportions of the boundingbox,
-> when your desired maximum x proportion is N then, and for y ..... and z, call:


model.setLocalScale(N / bb.xExtent, N / bb.yExtent, N / bb.zExtent);


update the GeometricState and add to the rootNode.

there you go


okay seems easy enough thx for quick reply I'm assuming for this to work i can't have         charNode.setModelBound(new BoundingBox);

so i did

BoundingBox bb = new BoundingBox();
        charNode.setModelBound(bb);
        charNode.updateModelBound();
Vector3f localScale = new Vector3f(bb.xExtent,bb.yExtent,bb.zExtent);
rootNode.setLocalScale(localScale);

but i receive an issue

Mar 19, 2009 12:12:17 PM com.jmex.game.DefaultUncaughtExceptionHandler uncaughtException
SEVERE: Main game loop broken by uncaught exception
java.lang.IllegalArgumentException: scale must not have 0 as a component (geom 'Examples/Ninja')!
   at com.jmex.physics.impl.ode.geometry.OdeBox.updateWorldVectors(OdeBox.java:69)
   at com.jme.scene.Spatial.updateWorldData(Spatial.java:552)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jme.scene.Node.updateWorldData(Node.java:395)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jme.scene.Node.updateWorldData(Node.java:395)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jme.scene.Node.updateWorldData(Node.java:395)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jmex.game.state.BasicGameState.update(BasicGameState.java:71)
   at com.jmex.physics.util.states.PhysicsGameState.update(PhysicsGameState.java:52)
   at com.tps1.GameState.DefineGameState.update(DefineGameState.java:48)
   at com.jmex.game.state.GameStateNode.update(GameStateNode.java:71)
   at com.jmex.game.StandardGame.update(StandardGame.java:381)
   at com.jmex.game.StandardGame.run(StandardGame.java:250)
   at java.lang.Thread.run(Thread.java:619)



if i do
float N=324;//or any other value
        Vector3f localScale = new Vector3f(N/bb.xExtent,N/bb.yExtent,N/bb.zExtent);
it runs however nothing shows

thats expected


Vector3f localScale = new Vector3f(bb.xExtent,bb.yExtent,bb.zExtent);



if the model is already 324 units long you scale it by 324 which makes a model 324^2 long
dhdd said:

thats expected

Vector3f localScale = new Vector3f(bb.xExtent,bb.yExtent,bb.zExtent);



if the model is already 324 units long you scale it by 324 which makes a model 324^2 long


that wasn't it i'm unsure what that issue really was but i got it working using

//temporary reduction in size
float N=2;
BoundingBox bb = (BoundingBox) charNode.getWorldBound();
        Vector3f localScale = new Vector3f(N/bb.xExtent,N/bb.yExtent,N/bb.zExtent);
rootNode.setLocalScale(localScale);
        charNode.updateModelBound();

however it doesn't retain its original scale example would be i think its the y or x axis it seems disporportional

float wantedScale = Math.min(N/xExtent, N/yExtent);

wantedScale = Math.min(N/zExtent, wantedScale);

blaNode.setLocalScale(wantedScale);

hmm it seems to work if i call



rootNode.updateGeometricState(0, true);



before I do the bounding box thing but do I have to call it after I attach the child as well as at the end of the code

hmm thx a lot for the previous replies however i seem to be having some issues and it seems to be related to the scaling of the object can i ask if the update methods are called appropriately as some times even though rare the object is smaller than usual



the comments are out of sync due to recent excessivs changes to the class


//Initalizes system
   private void init(PhysicsSpace Space) {      
      physNode=Space.createDynamicNode();physNode.setName("physNode");
      rootNode.attachChild(physNode);
      //Loads Inital Model//////////////////////////////////
       charNode = getCharacter();
       
      charNode.updateModelBound(); charNode.updateWorldBound();
      /////////////////////////////////////////      
      //sets up model to be deployed
      //temporary reduction in size
      float N=1;
      BoundingBox bb = (BoundingBox) charNode.getWorldBound();
      float wantedScale = Math.min(N/bb.xExtent, N/bb.yExtent);
      wantedScale = Math.min(N/bb.zExtent, wantedScale);
      charNode.setLocalScale(wantedScale);   
      
       //attach charNode to tree
      physNode.attachChild(charNode);
      charNode.setModelBound(new BoundingBox());     
      charNode.updateModelBound(); charNode.updateWorldBound();
      rootNode.updateWorldBound();
      
   

      charNode.updateGeometricState(0, false);
      rootNode.updateWorldBound();
      
      rootNode.updateGeometricState(0, false);
   
       charNode.updateRenderState();

      
   }   

after all the nodes are attached,



rootNode.updateRenderState();
rootNode.updateGeometricState(0.0f, true);



should be enough as for updating.

try to print a log output of the various stages of wantedScale per loaded model and post back the output.

dhdd said:

try to print a log output of the various stages of wantedScale per loaded model and post back the output.


hmm i've found that the wanted scale is distorted from the begining according to these results

The first one is when its correct the second one is when its extremly small
code is


 baseNode = new Node(baseNodeName);
        rootNode.attachChild(baseNode);
          
      //Loads Inital Model//////////////////////////////////
       charNode = getCharacter(baseNodeName);       

       //reduction in based on scale
      charNode.updateGeometricState(0.0f, false);
      float N=1;
      BoundingBox bb = (BoundingBox) charNode.getWorldBound();
      logger.info("Boudning Box Value: "+bb);
      float wantedScale = Math.min(N/bb.xExtent, N/bb.yExtent);
      logger.info("wantedScale created: "+wantedScale+ " Character size:" + charNode.getLocalScale());
      wantedScale = Math.min(N/bb.zExtent, wantedScale);
      logger.info("wantedScale created: "+wantedScale+ " Character size:" + charNode.getLocalScale());
      charNode.setLocalScale(wantedScale);   
      logger.info("wantedScale created: "+wantedScale+ " Character size:" + charNode.getLocalScale() +"charter World Boundings"+(BoundingBox) charNode.getWorldBound());
      //////Sets up model to be deployed in world////////////
      charNode.setModelBound(new BoundingBox());     
      charNode.updateModelBound(); charNode.updateWorldBound();

      baseNode.attachChild(charNode);
      rootNode.updateRenderState();
      rootNode.updateGeometricState(0.0f, true);



perfect


INFO: Boudning Box Value: com.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=4.7984, Y=48.545094, Z=-0.6600504]  xExtent: 14.0626  yExtent: 48.836308  zExtent: 22.54625]
Apr 20, 2009 8:34:16 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:34:16 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:34:16 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=0.020476568, Y=0.020476568, Z=0.020476568]charter World Boundingscom.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=4.7984, Y=48.545094, Z=-0.6600504]  xExtent: 14.0626  yExtent: 48.836308  zExtent: 22.54625]



character scaled way too small yet proportional enough to allow physics engine to scale


INFO: Boudning Box Value: com.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=-7.000046, Y=0.7499466, Z=-90.3069]  xExtent: 207.00005  yExtent: 199.25006  zExtent: 112.1931]
Apr 20, 2009 8:35:22 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.004830917 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:35:22 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.004830917 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:35:22 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.004830917 Character size:com.jme.math.Vector3f [X=0.004830917, Y=0.004830917, Z=0.004830917]charter World Boundingscom.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=-7.000046, Y=0.7499466, Z=-90.3069]  xExtent: 207.00005  yExtent: 199.25006  zExtent: 112.1931]



bounding off screws up physics mechanics makes them a bit too big


INFO: Boudning Box Value: com.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=4.7984, Y=48.545094, Z=-0.6600504]  xExtent: 14.0626  yExtent: 48.836308  zExtent: 22.54625]
Apr 20, 2009 8:31:41 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:31:41 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:31:41 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=0.020476568, Y=0.020476568, Z=0.020476568]



if i get a call such as this the game crashes and says scale must not have 0 component but i belive thats after it gets to adding the physicsNodes to the base


Apr 20, 2009 8:41:24 PM com.tps1.character.playerGameState init
INFO: Boudning Box Value: com.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=4.7984, Y=48.545094, Z=-0.6600504]  xExtent: 14.0626  yExtent: 48.836308  zExtent: 22.54625]
Apr 20, 2009 8:41:24 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:41:24 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=1.0, Y=1.0, Z=1.0]
Apr 20, 2009 8:41:24 PM com.tps1.character.playerGameState init
INFO: wantedScale created: 0.020476568 Character size:com.jme.math.Vector3f [X=0.020476568, Y=0.020476568, Z=0.020476568]charter World Boundingscom.jme.scene.BoundingBox [Center: com.jme.math.Vector3f [X=4.7984, Y=48.545094, Z=-0.6600504]  xExtent: 14.0626  yExtent: 48.836308  zExtent: 22.54625]


could thier be an issue with the actual method returning different bounds because sometimes in my physics implementation when i call the bounding again i get a compeltly different call from the last one recieved at the end of this class and it messes up the physics implementation as well as make the character smaller than intended

would this be better



float N=CharacterStats.get().getWorldScale();
      theNode.updateWorldBound();
      Spatial net = (Spatial)theNode.getChild(0);
      BoundingBox bb = (BoundingBox) ((Geometry)net).getModelBound();   
      float wantedScale = Math.min(Math.min(N/bb.xExtent, N/bb.yExtent),N/bb.zExtent);      
      theNode.setLocalScale(wantedScale);   
      theNode.setModelBound(new BoundingBox());
      theNode.updateModelBound();
      theNode.updateGeometricState(0, true);
      theNode.updateWorldBound();

can't you simply use fixed scale values, instead of computing them somehow?