Search in sources :

Example 1 with Quad

use of com.jme3.scene.shape.Quad in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method generateTSpaces.

static boolean generateTSpaces(TSpace[] psTspace, final TriInfo[] pTriInfos, final Group[] pGroups, final int iNrActiveGroups, final int[] piTriListIn, final float fThresCos, final MikkTSpaceContext mikkTSpace) {
    TSpace[] pSubGroupTspace;
    SubGroup[] pUniSubGroups;
    int[] pTmpMembers;
    int iMaxNrFaces = 0, iUniqueTspaces = 0, g = 0, i = 0;
    for (g = 0; g < iNrActiveGroups; g++) {
        if (iMaxNrFaces < pGroups[g].nrFaces) {
            iMaxNrFaces = pGroups[g].nrFaces;
        }
    }
    if (iMaxNrFaces == 0) {
        return true;
    }
    // make initial allocations
    pSubGroupTspace = new TSpace[iMaxNrFaces];
    pUniSubGroups = new SubGroup[iMaxNrFaces];
    pTmpMembers = new int[iMaxNrFaces];
    iUniqueTspaces = 0;
    for (g = 0; g < iNrActiveGroups; g++) {
        final Group pGroup = pGroups[g];
        int iUniqueSubGroups = 0, s = 0;
        for (// triangles
        i = 0; // triangles
        i < pGroup.nrFaces; // triangles
        i++) {
            // triangle number
            final int f = pGroup.faceIndices.get(i);
            int index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0, l = 0;
            SubGroup tmp_group = new SubGroup();
            boolean bFound;
            Vector3f n, vOs, vOt;
            if (pTriInfos[f].assignedGroup[0] == pGroup) {
                index = 0;
            } else if (pTriInfos[f].assignedGroup[1] == pGroup) {
                index = 1;
            } else if (pTriInfos[f].assignedGroup[2] == pGroup) {
                index = 2;
            }
            assert (index >= 0 && index < 3);
            iVertIndex = piTriListIn[f * 3 + index];
            assert (iVertIndex == pGroup.vertexRepresentitive);
            // is normalized already
            n = getNormal(mikkTSpace, iVertIndex);
            // project
            vOs = pTriInfos[f].os.subtract(n.mult(n.dot(pTriInfos[f].os)));
            vOt = pTriInfos[f].ot.subtract(n.mult(n.dot(pTriInfos[f].ot)));
            vOs.normalizeLocal();
            vOt.normalizeLocal();
            // original face number
            iOF_1 = pTriInfos[f].orgFaceNumber;
            iMembers = 0;
            for (j = 0; j < pGroup.nrFaces; j++) {
                // triangle number
                final int t = pGroup.faceIndices.get(j);
                final int iOF_2 = pTriInfos[t].orgFaceNumber;
                // project
                Vector3f vOs2 = pTriInfos[t].os.subtract(n.mult(n.dot(pTriInfos[t].os)));
                Vector3f vOt2 = pTriInfos[t].ot.subtract(n.mult(n.dot(pTriInfos[t].ot)));
                vOs2.normalizeLocal();
                vOt2.normalizeLocal();
                {
                    final boolean bAny = ((pTriInfos[f].flag | pTriInfos[t].flag) & GROUP_WITH_ANY) != 0;
                    // make sure triangles which belong to the same quad are joined.
                    final boolean bSameOrgFace = iOF_1 == iOF_2;
                    final float fCosS = vOs.dot(vOs2);
                    final float fCosT = vOt.dot(vOt2);
                    // sanity check
                    assert (f != t || bSameOrgFace);
                    if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos)) {
                        pTmpMembers[iMembers++] = t;
                    }
                }
            }
            // sort pTmpMembers
            tmp_group.nrFaces = iMembers;
            tmp_group.triMembers = pTmpMembers;
            if (iMembers > 1) {
                quickSort(pTmpMembers, 0, iMembers - 1, INTERNAL_RND_SORT_SEED);
            }
            // look for an existing match
            bFound = false;
            l = 0;
            while (l < iUniqueSubGroups && !bFound) {
                bFound = compareSubGroups(tmp_group, pUniSubGroups[l]);
                if (!bFound) {
                    ++l;
                }
            }
            // assign tangent space index
            assert (bFound || l == iUniqueSubGroups);
            // if no match was found we allocate a new subgroup
            if (!bFound) {
                // insert new subgroup
                int[] pIndices = new int[iMembers];
                pUniSubGroups[iUniqueSubGroups] = new SubGroup();
                pUniSubGroups[iUniqueSubGroups].nrFaces = iMembers;
                pUniSubGroups[iUniqueSubGroups].triMembers = pIndices;
                System.arraycopy(tmp_group.triMembers, 0, pIndices, 0, iMembers);
                //memcpy(pIndices, tmp_group.pTriMembers, iMembers*sizeof(int));
                pSubGroupTspace[iUniqueSubGroups] = evalTspace(tmp_group.triMembers, iMembers, piTriListIn, pTriInfos, mikkTSpace, pGroup.vertexRepresentitive);
                ++iUniqueSubGroups;
            }
            // output tspace
            {
                final int iOffs = pTriInfos[f].tSpacesOffs;
                final int iVert = pTriInfos[f].vertNum[index];
                TSpace pTS_out = psTspace[iOffs + iVert];
                assert (pTS_out.counter < 2);
                assert (((pTriInfos[f].flag & ORIENT_PRESERVING) != 0) == pGroup.orientPreservering);
                if (pTS_out.counter == 1) {
                    pTS_out.set(avgTSpace(pTS_out, pSubGroupTspace[l]));
                    // update counter
                    pTS_out.counter = 2;
                    pTS_out.orient = pGroup.orientPreservering;
                } else {
                    assert (pTS_out.counter == 0);
                    pTS_out.set(pSubGroupTspace[l]);
                    // update counter
                    pTS_out.counter = 1;
                    pTS_out.orient = pGroup.orientPreservering;
                }
            }
        }
        iUniqueTspaces += iUniqueSubGroups;
    }
    return true;
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 2 with Quad

use of com.jme3.scene.shape.Quad in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method initTriInfo.

static void initTriInfo(TriInfo[] pTriInfos, final int[] piTriListIn, final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn) {
    // generate neighbor info list
    for (int f = 0; f < iNrTrianglesIn; f++) {
        for (int i = 0; i < 3; i++) {
            pTriInfos[f].faceNeighbors[i] = -1;
            pTriInfos[f].assignedGroup[i] = null;
            pTriInfos[f].os.x = 0.0f;
            pTriInfos[f].os.y = 0.0f;
            pTriInfos[f].os.z = 0.0f;
            pTriInfos[f].ot.x = 0.0f;
            pTriInfos[f].ot.y = 0.0f;
            pTriInfos[f].ot.z = 0.0f;
            pTriInfos[f].magS = 0;
            pTriInfos[f].magT = 0;
            // assumed bad
            pTriInfos[f].flag |= GROUP_WITH_ANY;
        }
    }
    // evaluate first order derivatives
    for (int f = 0; f < iNrTrianglesIn; f++) {
        // initial values
        final Vector3f v1 = getPosition(mikkTSpace, piTriListIn[f * 3 + 0]);
        final Vector3f v2 = getPosition(mikkTSpace, piTriListIn[f * 3 + 1]);
        final Vector3f v3 = getPosition(mikkTSpace, piTriListIn[f * 3 + 2]);
        final Vector3f t1 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 0]);
        final Vector3f t2 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 1]);
        final Vector3f t3 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 2]);
        final float t21x = t2.x - t1.x;
        final float t21y = t2.y - t1.y;
        final float t31x = t3.x - t1.x;
        final float t31y = t3.y - t1.y;
        final Vector3f d1 = v2.subtract(v1);
        final Vector3f d2 = v3.subtract(v1);
        final float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
        //assert(fSignedAreaSTx2!=0);
        // eq 18
        Vector3f vOs = d1.mult(t31y).subtract(d2.mult(t21y));
        // eq 19
        Vector3f vOt = d1.mult(-t31x).add(d2.mult(t21x));
        pTriInfos[f].flag |= (fSignedAreaSTx2 > 0 ? ORIENT_PRESERVING : 0);
        if (isNotZero(fSignedAreaSTx2)) {
            final float fAbsArea = Math.abs(fSignedAreaSTx2);
            final float fLenOs = vOs.length();
            final float fLenOt = vOt.length();
            final float fS = (pTriInfos[f].flag & ORIENT_PRESERVING) == 0 ? (-1.0f) : 1.0f;
            if (isNotZero(fLenOs)) {
                pTriInfos[f].os = vOs.multLocal(fS / fLenOs);
            }
            if (isNotZero(fLenOt)) {
                pTriInfos[f].ot = vOt.multLocal(fS / fLenOt);
            }
            // evaluate magnitudes prior to normalization of vOs and vOt
            pTriInfos[f].magS = fLenOs / fAbsArea;
            pTriInfos[f].magT = fLenOt / fAbsArea;
            // if this is a good triangle
            if (isNotZero(pTriInfos[f].magS) && isNotZero(pTriInfos[f].magT)) {
                pTriInfos[f].flag &= (~GROUP_WITH_ANY);
            }
        }
    }
    // force otherwise healthy quads to a fixed orientation
    int t = 0;
    while (t < (iNrTrianglesIn - 1)) {
        final int iFO_a = pTriInfos[t].orgFaceNumber;
        final int iFO_b = pTriInfos[t + 1].orgFaceNumber;
        if (iFO_a == iFO_b) {
            // this is a quad
            final boolean bIsDeg_a = (pTriInfos[t].flag & MARK_DEGENERATE) != 0;
            final boolean bIsDeg_b = (pTriInfos[t + 1].flag & MARK_DEGENERATE) != 0;
            // DegenPrologue(), but just in case check bIsDeg_a and bIsDeg_a are false
            if ((bIsDeg_a || bIsDeg_b) == false) {
                final boolean bOrientA = (pTriInfos[t].flag & ORIENT_PRESERVING) != 0;
                final boolean bOrientB = (pTriInfos[t + 1].flag & ORIENT_PRESERVING) != 0;
                // if this happens the quad has extremely bad mapping!!
                if (bOrientA != bOrientB) {
                    //printf("found quad with bad mapping\n");
                    boolean bChooseOrientFirstTri = false;
                    if ((pTriInfos[t + 1].flag & GROUP_WITH_ANY) != 0) {
                        bChooseOrientFirstTri = true;
                    } else if (calcTexArea(mikkTSpace, Arrays.copyOfRange(piTriListIn, t * 3 + 0, t * 3 + 3)) >= calcTexArea(mikkTSpace, Arrays.copyOfRange(piTriListIn, (t + 1) * 3 + 0, (t + 1) * 3 + 3))) {
                        bChooseOrientFirstTri = true;
                    }
                    // force match
                    {
                        final int t0 = bChooseOrientFirstTri ? t : (t + 1);
                        final int t1 = bChooseOrientFirstTri ? (t + 1) : t;
                        // clear first
                        pTriInfos[t1].flag &= (~ORIENT_PRESERVING);
                        // copy bit
                        pTriInfos[t1].flag |= (pTriInfos[t0].flag & ORIENT_PRESERVING);
                    }
                }
            }
            t += 2;
        } else {
            ++t;
        }
    }
    // match up edge pairs
    {
        //Edge * pEdges = (Edge *) malloc(sizeof(Edge)*iNrTrianglesIn*3);
        Edge[] pEdges = new Edge[iNrTrianglesIn * 3];
        //TODO nehon weird... original algorithm check if pEdges is null but it's just been allocated... weirder, it does soemthing different if the edges are null...
        //    if (pEdges==null)
        //      BuildNeighborsSlow(pTriInfos, piTriListIn, iNrTrianglesIn);
        //    else
        //    {
        buildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn);
    //    }
    }
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 3 with Quad

use of com.jme3.scene.shape.Quad in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method DegenEpilogue.

static void DegenEpilogue(TSpace[] psTspace, TriInfo[] pTriInfos, int[] piTriListIn, final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn, final int iTotTris) {
    // punishment for degenerate triangles is O(N^2)
    for (int t = iNrTrianglesIn; t < iTotTris; t++) {
        // degenerate triangles on a quad with one good triangle are skipped
        // here but processed in the next loop
        final boolean bSkip = (pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0;
        if (!bSkip) {
            for (int i = 0; i < 3; i++) {
                final int index1 = piTriListIn[t * 3 + i];
                // search through the good triangles
                boolean bNotFound = true;
                int j = 0;
                while (bNotFound && j < (3 * iNrTrianglesIn)) {
                    final int index2 = piTriListIn[j];
                    if (index1 == index2) {
                        bNotFound = false;
                    } else {
                        ++j;
                    }
                }
                if (!bNotFound) {
                    final int iTri = j / 3;
                    final int iVert = j % 3;
                    final int iSrcVert = pTriInfos[iTri].vertNum[iVert];
                    final int iSrcOffs = pTriInfos[iTri].tSpacesOffs;
                    final int iDstVert = pTriInfos[t].vertNum[i];
                    final int iDstOffs = pTriInfos[t].tSpacesOffs;
                    // copy tspace
                    psTspace[iDstOffs + iDstVert] = psTspace[iSrcOffs + iSrcVert];
                }
            }
        }
    }
    // deal with degenerate quads with one good triangle
    for (int t = 0; t < iNrTrianglesIn; t++) {
        // other triangle is degenerate
        if ((pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0) {
            byte[] pV = pTriInfos[t].vertNum;
            int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]);
            int iMissingIndex = 0;
            if ((iFlag & 2) == 0) {
                iMissingIndex = 1;
            } else if ((iFlag & 4) == 0) {
                iMissingIndex = 2;
            } else if ((iFlag & 8) == 0) {
                iMissingIndex = 3;
            }
            int iOrgF = pTriInfos[t].orgFaceNumber;
            Vector3f vDstP = getPosition(mikkTSpace, makeIndex(iOrgF, iMissingIndex));
            boolean bNotFound = true;
            int i = 0;
            while (bNotFound && i < 3) {
                final int iVert = pV[i];
                final Vector3f vSrcP = getPosition(mikkTSpace, makeIndex(iOrgF, iVert));
                if (vSrcP.equals(vDstP)) {
                    final int iOffs = pTriInfos[t].tSpacesOffs;
                    psTspace[iOffs + iMissingIndex] = psTspace[iOffs + iVert];
                    bNotFound = false;
                } else {
                    ++i;
                }
            }
            assert (!bNotFound);
        }
    }
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 4 with Quad

use of com.jme3.scene.shape.Quad in project jmonkeyengine by jMonkeyEngine.

the class TerrainGridTileLoaderTest method simpleInitApp.

@Override
public void simpleInitApp() {
    File file = new File("TerrainGridTestData.zip");
    if (!file.exists()) {
        assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/TerrainGridTestData.zip", HttpZipLocator.class);
    } else {
        assetManager.registerLocator("TerrainGridTestData.zip", ZipLocator.class);
    }
    this.flyCam.setMoveSpeed(100f);
    ScreenshotAppState state = new ScreenshotAppState();
    this.stateManager.attach(state);
    // TERRAIN TEXTURE material
    this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
    // Parameters to material:
    // regionXColorMap: X = 1..4 the texture that should be appliad to state X
    // regionX: a Vector3f containing the following information:
    //      regionX.x: the start height of the region
    //      regionX.y: the end height of the region
    //      regionX.z: the texture scale for the region
    //  it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
    // slopeColorMap: the texture to be used for cliffs, and steep mountain sites
    // slopeTileFactor: the texture scale for slopes
    // terrainSize: the total size of the terrain (used for scaling the texture)
    // GRASS texture
    Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
    grass.setWrap(WrapMode.Repeat);
    this.mat_terrain.setTexture("region1ColorMap", grass);
    this.mat_terrain.setVector3("region1", new Vector3f(88, 200, this.grassScale));
    // DIRT texture
    Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
    dirt.setWrap(WrapMode.Repeat);
    this.mat_terrain.setTexture("region2ColorMap", dirt);
    this.mat_terrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale));
    // ROCK texture
    Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
    rock.setWrap(WrapMode.Repeat);
    this.mat_terrain.setTexture("region3ColorMap", rock);
    this.mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale));
    this.mat_terrain.setTexture("region4ColorMap", rock);
    this.mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale));
    this.mat_terrain.setTexture("slopeColorMap", rock);
    this.mat_terrain.setFloat("slopeTileFactor", 32);
    this.mat_terrain.setFloat("terrainSize", 129);
    //quad.getHeightMap(), terrain.getLocalScale()), 0
    AssetTileLoader grid = new AssetTileLoader(assetManager, "testgrid", "TerrainGrid");
    this.terrain = new TerrainGrid("terrain", 65, 257, grid);
    this.terrain.setMaterial(this.mat_terrain);
    this.terrain.setLocalTranslation(0, 0, 0);
    this.terrain.setLocalScale(2f, 1f, 2f);
    //        try {
    //            BinaryExporter.getInstance().save(terrain, new File("/Users/normenhansen/Documents/Code/jme3/engine/src/test-data/TerrainGrid/"
    //                    + "TerrainGrid.j3o"));
    //        } catch (IOException ex) {
    //            Logger.getLogger(TerrainFractalGridTest.class.getName()).log(Level.SEVERE, null, ex);
    //        }
    this.rootNode.attachChild(this.terrain);
    TerrainLodControl control = new TerrainGridLodControl(this.terrain, getCamera());
    // patch size, and a multiplier
    control.setLodCalculator(new DistanceLodCalculator(65, 2.7f));
    this.terrain.addControl(control);
    final BulletAppState bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    this.getCamera().setLocation(new Vector3f(0, 256, 0));
    this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
    if (usePhysics) {
        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
        player3 = new CharacterControl(capsuleShape, 0.5f);
        player3.setJumpSpeed(20);
        player3.setFallSpeed(10);
        player3.setGravity(10);
        player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
        bulletAppState.getPhysicsSpace().add(player3);
        terrain.addListener(new TerrainGridListener() {

            public void gridMoved(Vector3f newCenter) {
            }

            public void tileAttached(Vector3f cell, TerrainQuad quad) {
                while (quad.getControl(RigidBodyControl.class) != null) {
                    quad.removeControl(RigidBodyControl.class);
                }
                quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
                bulletAppState.getPhysicsSpace().add(quad);
            }

            public void tileDetached(Vector3f cell, TerrainQuad quad) {
                if (quad.getControl(RigidBodyControl.class) != null) {
                    bulletAppState.getPhysicsSpace().remove(quad);
                    quad.removeControl(RigidBodyControl.class);
                }
            }
        });
    }
    this.initKeys();
}
Also used : CharacterControl(com.jme3.bullet.control.CharacterControl) TerrainGrid(com.jme3.terrain.geomipmap.TerrainGrid) TerrainGridListener(com.jme3.terrain.geomipmap.TerrainGridListener) Material(com.jme3.material.Material) CapsuleCollisionShape(com.jme3.bullet.collision.shapes.CapsuleCollisionShape) Texture(com.jme3.texture.Texture) DistanceLodCalculator(com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator) RigidBodyControl(com.jme3.bullet.control.RigidBodyControl) TerrainGridLodControl(com.jme3.terrain.geomipmap.TerrainGridLodControl) AssetTileLoader(com.jme3.terrain.geomipmap.grid.AssetTileLoader) ColorRGBA(com.jme3.math.ColorRGBA) Vector3f(com.jme3.math.Vector3f) BulletAppState(com.jme3.bullet.BulletAppState) HeightfieldCollisionShape(com.jme3.bullet.collision.shapes.HeightfieldCollisionShape) TerrainLodControl(com.jme3.terrain.geomipmap.TerrainLodControl) ScreenshotAppState(com.jme3.app.state.ScreenshotAppState) File(java.io.File) TerrainQuad(com.jme3.terrain.geomipmap.TerrainQuad)

Example 5 with Quad

use of com.jme3.scene.shape.Quad in project jmonkeyengine by jMonkeyEngine.

the class TestAnisotropicFilter method simpleInitApp.

@Override
public void simpleInitApp() {
    maxAniso = renderer.getLimits().get(Limits.TextureAnisotropy);
    flyCam.setDragToRotate(true);
    flyCam.setMoveSpeed(100);
    cam.setLocation(new Vector3f(197.02617f, 4.6769195f, -194.89545f));
    cam.setRotation(new Quaternion(0.07921988f, 0.8992258f, -0.18292196f, 0.38943136f));
    Quad q = new Quad(1000, 1000);
    q.scaleTextureCoordinates(new Vector2f(1000, 1000));
    Geometry geom = new Geometry("quad", q);
    geom.rotate(-FastMath.HALF_PI, 0, 0);
    geom.setMaterial(createCheckerBoardMaterial(assetManager));
    rootNode.attachChild(geom);
    inputManager.addMapping("higher", new KeyTrigger(KeyInput.KEY_1));
    inputManager.addMapping("lower", new KeyTrigger(KeyInput.KEY_2));
    inputManager.addListener(this, "higher");
    inputManager.addListener(this, "lower");
}
Also used : Geometry(com.jme3.scene.Geometry) Quad(com.jme3.scene.shape.Quad) Quaternion(com.jme3.math.Quaternion) Vector2f(com.jme3.math.Vector2f) Vector3f(com.jme3.math.Vector3f) KeyTrigger(com.jme3.input.controls.KeyTrigger)

Aggregations

Geometry (com.jme3.scene.Geometry)36 Quad (com.jme3.scene.shape.Quad)35 Material (com.jme3.material.Material)30 Vector3f (com.jme3.math.Vector3f)23 Node (com.jme3.scene.Node)11 Spatial (com.jme3.scene.Spatial)10 DirectionalLight (com.jme3.light.DirectionalLight)9 Quaternion (com.jme3.math.Quaternion)9 Texture (com.jme3.texture.Texture)9 TerrainQuad (com.jme3.terrain.geomipmap.TerrainQuad)7 ColorRGBA (com.jme3.math.ColorRGBA)6 Vector2f (com.jme3.math.Vector2f)6 AmbientLight (com.jme3.light.AmbientLight)5 Mesh (com.jme3.scene.Mesh)5 Texture2D (com.jme3.texture.Texture2D)5 Picture (com.jme3.ui.Picture)5 File (java.io.File)5 ScreenshotAppState (com.jme3.app.state.ScreenshotAppState)4 BulletAppState (com.jme3.bullet.BulletAppState)4 CapsuleCollisionShape (com.jme3.bullet.collision.shapes.CapsuleCollisionShape)4