2012-01-25 23 views
6

JME3'ü öğreniyorum ve kendi yükseklik haritasını oluşturmayı ve örnek kodun bir kısmını değiştirmeyi vb. Başarabildim. Şimdi, Blender ile çok basit, 4 duvarlı, çatısız bir oda yarattım. bir Wavefront obj dosyası gibi ve benim sahnedeki halkına bunları yüklenen (I terrain düğüme saldırdılar.JMonkeyEngine: Dinamik olarak yüklenmiş modellerde çarpışma algılaması

Şimdi, benim terrain taşımak ve çevresinde atlayabilir oyuncu böylece uygulanan bir çarpışma algılama vardır, ama aynı zamanda doğru yürüyebilir Benim modelimin duvarları boyunca bulabildiğim tüm örnekler zaten önceden yapılmış bir sahneyi yükler, ve hala oyuncunun yüklü modelden neden çıktığı konusunda hala clueless miyim?

Sor Büyük kod için ry, ama başka nasıl yapabileceğimi göremedim.

Yani
public class Main extends SimpleApplication 
     implements ActionListener { 

    private BulletAppState bulletAppState; 
    private RigidBodyControl landscape; 
    private CharacterControl player; 
    private Vector3f walkDirection = new Vector3f(); 
    private boolean left = false, right = false, up = false, down = false; 
    private TerrainQuad terrain; 
    private Material mat_terrain; 

    public static void main(String[] args) { 
     AppSettings settings = new AppSettings(true); 
     settings.setResolution(1366, 768); 
     settings.setFullscreen(true); 

     Main app = new Main(); 
     app.setSettings(settings); 
     app.setShowSettings(false); 
     app.start(); 
    } 

    @Override 
    public void simpleInitApp() { 
     /** Set up Physics */ 
     bulletAppState = new BulletAppState(); 
     stateManager.attach(bulletAppState); 
     //bulletAppState.getPhysicsSpace().enableDebug(assetManager); 

     flyCam.setMoveSpeed(200); 
     setUpKeys(); 

     /** 1. Create terrain material and load four textures into it. */ 
     mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); 

     /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ 
     mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/terrain/island_1_alpha1.png")); 

     /** 1.2) Add GRASS texture into the red layer (Tex1). */ 
     Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); 
     grass.setWrap(WrapMode.Repeat); 
     mat_terrain.setTexture("Tex1", grass); 
     mat_terrain.setFloat("Tex1Scale", 64f); 

     /** 1.3) Add DIRT texture into the green layer (Tex2) */ 
     Texture dirt = assetManager.loadTexture("Textures/rocks.jpg"); 
     dirt.setWrap(WrapMode.Repeat); 
     mat_terrain.setTexture("Tex2", dirt); 
     mat_terrain.setFloat("Tex2Scale", 32f); 

     /** 1.4) Add ROAD texture into the blue layer (Tex3) */ 
     Texture rock = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); 
     rock.setWrap(WrapMode.Repeat); 
     mat_terrain.setTexture("Tex3", rock); 
     mat_terrain.setFloat("Tex3Scale", 128f); 

     /** 2. Create the height map */ 
     AbstractHeightMap heightmap = null; 
     Texture heightMapImage = assetManager.loadTexture("Textures/terrain/island_1.png"); 
     heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); 
     heightmap.load(); 

     /** 3. We have prepared material and heightmap. 
     * Now we create the actual terrain: 
     * 3.1) Create a TerrainQuad and name it "my terrain". 
     * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65. 
     * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. 
     * 3.4) As LOD step scale we supply Vector3f(1,1,1). 
     * 3.5) We supply the prepared heightmap itself. 
     */ 
     terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap()); 

     /** 4. We give the terrain its material, position & scale it, and attach it. */ 
     terrain.setMaterial(mat_terrain); 
     terrain.setLocalTranslation(0, -170, 0); 
     terrain.setLocalScale(2f, 1f, 2f); 
     rootNode.attachChild(terrain); 

     /** 4.5. Load some models */ 
     Spatial building = assetManager.loadModel("Models/building1.obj"); 
     Material mat_default = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); 
     building.setMaterial(mat_default); 
     building.setLocalTranslation(90, 117, 90); 
     building.setLocalScale(5f, 5f, 5f); 
     terrain.attachChild(building); 


     /** 4.6. Load Sky */ 
     rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false)); 

     /** 4.7. Load water */ 

     // we create a water processor 
     SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager); 
     waterProcessor.setReflectionScene(rootNode); 

     // we set the water plane 
     Vector3f waterLocation = new Vector3f(0, -58, 0); 
     waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y))); 
     viewPort.addProcessor(waterProcessor); 

     // we set wave properties 
     waterProcessor.setWaterDepth(50);   // transparency of water 
     waterProcessor.setDistortionScale(0.05f); // strength of waves 
     waterProcessor.setWaveSpeed(0.05f);  // speed of waves 

     // we define the wave size by setting the size of the texture coordinates 
     Quad quad = new Quad(1000, 1000); 
     quad.scaleTextureCoordinates(new Vector2f(10f, 10f)); 

     // we create the water geometry from the quad 
     Geometry water = new Geometry("water", quad); 
     water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X)); 
     water.setLocalTranslation(-500, -58, 500); 
     water.setShadowMode(ShadowMode.Receive); 
     water.setMaterial(waterProcessor.getMaterial()); 
     rootNode.attachChild(water); 

     /** 5. The LOD (level of detail) depends on were the camera is: */ 
     List<Camera> cameras = new ArrayList<Camera>(); 
     cameras.add(getCamera()); 
     TerrainLodControl control = new TerrainLodControl(terrain, cameras); 
     terrain.addControl(control); 

     /** 6. Add physics: */ 
     // We set up collision detection for the scene by creating a 
     // compound collision shape and a static RigidBodyControl with mass zero.*/ 
     CollisionShape terrainShape = CollisionShapeFactory.createMeshShape(terrain); 
     landscape = new RigidBodyControl(terrainShape, 0); 
     terrain.addControl(landscape); 
     terrain.addControl(new RigidBodyControl(CollisionShapeFactory.createMeshShape(building), 0)); 

     // We set up collision detection for the player by creating 
     // a capsule collision shape and a CharacterControl. 
     // The CharacterControl offers extra settings for 
     // size, stepheight, jumping, falling, and gravity. 
     // We also put the player in its starting position. 
     CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); 
     player = new CharacterControl(capsuleShape, 0.05f); 
     player.setJumpSpeed(50); 
     player.setFallSpeed(70); 
     player.setGravity(100); 
     player.setPhysicsLocation(new Vector3f(50, 100, 100)); 

     // We attach the scene and the player to the rootnode and the physics space, 
     // to make them appear in the game world. 
     bulletAppState.getPhysicsSpace().add(terrain); 
     bulletAppState.getPhysicsSpace().add(player); 


    } 

    /** We over-write some navigational key mappings here, so we can 
    * add physics-controlled walking and jumping: */ 
    private void setUpKeys() { 
     inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A)); 
     inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); 
     inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W)); 
     inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); 
     inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); 
     inputManager.addListener(this, "Left"); 
     inputManager.addListener(this, "Right"); 
     inputManager.addListener(this, "Up"); 
     inputManager.addListener(this, "Down"); 
     inputManager.addListener(this, "Jump"); 
    } 

    /** These are our custom actions triggered by key presses. 
     * We do not walk yet, we just keep track of the direction the user pressed. */ 
    public void onAction(String binding, boolean value, float tpf) { 
     if (binding.equals("Left")) { 
      if (value) { 
       left = true; 
      } else { 
       left = false; 
      } 
     } else if (binding.equals("Right")) { 
      if (value) { 
       right = true; 
      } else { 
       right = false; 
      } 
     } else if (binding.equals("Up")) { 
      if (value) { 
       up = true; 
      } else { 
       up = false; 
      } 
     } else if (binding.equals("Down")) { 
      if (value) { 
       down = true; 
      } else { 
       down = false; 
      } 
     } else if (binding.equals("Jump")) { 
      player.jump(); 
     } 
    } 

    /** 
    * This is the main event loop--walking happens here. 
    * We check in which direction the player is walking by interpreting 
    * the camera direction forward (camDir) and to the side (camLeft). 
    * The setWalkDirection() command is what lets a physics-controlled player walk. 
    * We also make sure here that the camera moves with player. 
    */ 
    @Override 
    public void simpleUpdate(float tpf) { 
     Vector3f camDir = cam.getDirection().clone().multLocal(0.6f); 
     Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f); 
     walkDirection.set(0, 0, 0); 
     if (left) { 
      walkDirection.addLocal(camLeft); 
     } 
     if (right) { 
      walkDirection.addLocal(camLeft.negate()); 
     } 
     if (up) { 
      walkDirection.addLocal(camDir); 
     } 
     if (down) { 
      walkDirection.addLocal(camDir.negate()); 
     } 
     player.setWalkDirection(walkDirection); 
     cam.setLocation(player.getPhysicsLocation()); 
    } 
} 

, neden benim modeli çarpışma algılama uygulanmaz: fizik bölümünde /** 6. Add physics: */ uygulanır?

cevap

6

Cevabı buldum, here.

  1. bir CollisionShape oluşturun: sorunun çözümü budur.
  2. CollisionShape ve kütlesini sağlayarak bir PhysicsControl oluşturun. Örneğin. com.jme3.bullet.control.RigidBodyControl
  3. Mekansal'a PhysicsControl ekleyin. PhysicsControl öğesini
  4. physicsSpace nesnesine ekleyin. Spatial'i her zamanki gibi rootNode'a ekleyin.
  5. (İsteğe Bağlı) İstenirse, PhysicsCollisionEvents öğesine yanıt vermek için PhysicsCollisionListener arabirimini uygulayın.

Bu nedenle,

rootNode.attachChild(building); 

ve

bulletAppState.getPhysicsSpace().add(building); 
eklenerek

terrain.attachChild(building); 

yerine