/** {@inheritDoc} */ public Vector3f getIntersection(Ray ray, Spatial parent, Vector3f store, boolean local) { if (store == null) { store = new Vector3f(); } TrianglePickResults results = new TrianglePickResults(); results.setCheckDistance(true); Vector3f[] vertices = new Vector3f[3]; parent.findPick(ray, results); boolean hit = false; if (results.getNumber() > 0) { PickData data = results.getPickData(0); ArrayList<Integer> triangles = data.getTargetTris(); if (!triangles.isEmpty()) { TriMesh mesh = (TriMesh) data.getTargetMesh(); mesh.getTriangle(triangles.get(0).intValue(), vertices); for (int j = 0; j < vertices.length; j++) { mesh.localToWorld(vertices[j], vertices[j]); } hit = ray.intersectWhere(vertices[0], vertices[1], vertices[2], store); if (hit && local) { parent.worldToLocal(store, store); return store; } else if (hit && !local) { return store; } } } return null; }
private Node constructMesh() { Node toReturn = new Node("MD3 File"); for (int i = 0; i < head.numSurface; i++) { vkc = new KeyframeController(); MD3Surface thisSurface = surfaces[i]; TriMesh object = new TriMesh(thisSurface.name); object.setIndexBuffer(BufferUtils.createIntBuffer(thisSurface.triIndexes)); object.setVertexBuffer(BufferUtils.createFloatBuffer(thisSurface.verts[0])); object.setNormalBuffer(BufferUtils.createFloatBuffer(thisSurface.norms[0])); object.setTextureCoords(TexCoords.makeNew(thisSurface.texCoords)); toReturn.attachChild(object); vkc.setMorphingMesh(object); for (int j = 0; j < head.numFrames; j++) { TriMesh etm = new TriMesh(); etm.setVertexBuffer(BufferUtils.createFloatBuffer(thisSurface.verts[j])); etm.setNormalBuffer(BufferUtils.createFloatBuffer(thisSurface.norms[j])); vkc.setKeyframe(j, etm); } vkc.setActive(true); vkc.setSpeed(5); object.addController(vkc); toReturn.addController(vkc); } nullAll(); return toReturn; }
public void read(JMEImporter e) throws IOException { InputCapsule capsule = e.getCapsule(this); target = (TriangleBatch) capsule.readSavable("target", null); if (target != null && target.parentGeom == null) { if (motherMesh == null) { motherMesh = new TriMesh("mother"); motherMesh.clearBatches(); } motherMesh.addBatch(target); } super.read(e); }
@Override public void read(JMEImporter im) throws IOException { super.read(im); Savable[] temp = null; InputCapsule ic = im.getCapsule(this); // Read in texture map locations. this.color = ic.readString("ColorMap", null); this.normal = ic.readString("NormalMap", null); this.specular = ic.readString("SpecularMap", null); // Read in primitives. temp = ic.readSavableArray("Vertices", null); this.vertices = new IVertex[temp.length]; for (int i = 0; i < temp.length; i++) { this.vertices[i] = (IVertex) temp[i]; } temp = ic.readSavableArray("Triangles", null); this.triangles = new ITriangle[temp.length]; for (int i = 0; i < temp.length; i++) { this.triangles[i] = (ITriangle) temp[i]; } temp = ic.readSavableArray("Weights", null); this.weights = new IWeight[temp.length]; for (int i = 0; i < temp.length; i++) { this.weights[i] = (IWeight) temp[i]; } // Read in settings. this.anisotropic = ic.readInt("Anisotropic", 0); this.miniFilter = MinificationFilter.valueOf(ic.readString("MinFilter", null)); this.magFilter = MagnificationFilter.valueOf(ic.readString("MagFilter", null)); this.orientedBounding = ic.readBoolean("OrientedBounding", false); }
@Override public void write(JMEExporter ex) throws IOException { super.write(ex); OutputCapsule oc = ex.getCapsule(this); // Save all texture locations. TextureState state = (TextureState) this.getRenderState(StateType.Texture); Texture colorMap = state.getTexture(0); Texture normalMap = state.getTexture(1); Texture specularMap = state.getTexture(2); if (colorMap != null) { String colorRaw = colorMap.getImageLocation(); oc.write(colorRaw.substring(colorRaw.indexOf("/"), colorRaw.length()), "ColorMap", null); } if (normalMap != null) { String normalRaw = normalMap.getImageLocation(); oc.write(normalRaw.substring(normalRaw.indexOf("/"), normalRaw.length()), "NormalMap", null); } if (specularMap != null) { String specularRaw = specularMap.getImageLocation(); oc.write( specularRaw.substring(specularRaw.indexOf("/"), specularRaw.length()), "SpecularMap", null); } // Write out primitives. oc.write(this.vertices, "Vertices", null); oc.write(this.triangles, "Triangles", null); oc.write(this.weights, "Weights", null); // Write out settings. oc.write(this.anisotropic, "Anisotropic", 0); oc.write(this.miniFilter.name(), "MinFilter", null); oc.write(this.magFilter.name(), "MagFilter", null); oc.write(this.orientedBounding, "OrientedBounding", false); }
public static void generate(TriMesh mesh) { FloatBuffer tangents = BufferUtils.createFloatBuffer(mesh.getVertexCount() * 3); FloatBuffer binormals = BufferUtils.createFloatBuffer(mesh.getVertexCount() * 3); IntBuffer indexBuffer = mesh.getIndexBuffer(); FloatBuffer vertexBuffer = mesh.getVertexBuffer(); FloatBuffer textureBuffer = mesh.getTextureCoords(0).coords; indexBuffer.rewind(); Vector3f tangent = new Vector3f(); Vector3f binormal = new Vector3f(); Vector3f normal = new Vector3f(); Vector3f verts[] = new Vector3f[3]; Vector2f texcoords[] = new Vector2f[3]; for (int i = 0; i < 3; i++) { verts[i] = new Vector3f(); texcoords[i] = new Vector2f(); } for (int t = 0; t < indexBuffer.capacity() / 3; t++) { int index[] = new int[3]; for (int v = 0; v < 3; v++) { index[v] = indexBuffer.get(); verts[v].x = vertexBuffer.get(index[v] * 3); verts[v].y = vertexBuffer.get(index[v] * 3 + 1); verts[v].z = vertexBuffer.get(index[v] * 3 + 2); texcoords[v].x = textureBuffer.get(index[v] * 2); texcoords[v].y = textureBuffer.get(index[v] * 2 + 1); } computeTriangleTangentSpace(tangent, binormal, normal, verts, texcoords); for (int v = 0; v < 3; v++) { tangents.position(index[v] * 3); tangents.put(tangent.x); tangents.put(tangent.y); tangents.put(tangent.z); binormals.position(index[v] * 3); binormals.put(binormal.x); binormals.put(binormal.y); binormals.put(binormal.z); } } mesh.setTangentBuffer(tangents); mesh.setBinormalBuffer(binormals); }
public void initParticleLocation(int index) { Particle p = particles[index]; if (particleType == ParticleType.GeomMesh) { // Update the triangle model on each new particle creation. Vector3f[] vertices = new Vector3f[3]; ((TriMesh) psGeom).getTriangle(index, vertices); Triangle t = p.getTriangleModel(); if (t == null) t = new Triangle(vertices[0], vertices[1], vertices[2]); else for (int x = 0; x < 3; x++) t.set(x, vertices[x]); t.calculateCenter(); t.calculateNormal(); // turn the triangle corners into vector offsets from center for (int x = 0; x < 3; x++) { vertices[x].subtract(t.getCenter(), vertices[x]); t.set(x, vertices[x]); } p.setTriangleModel(t); psGeom.localToWorld(t.getCenter(), p.getPosition()); p.getPosition().multLocal(getInvScale()); } else if (getEmitType() == EmitType.Geometry) { if (getGeometry() != null && getGeometry() instanceof TriMesh) ((TriMesh) getGeometry()).randomPointOnTriangles(p.getPosition(), workVect3); else if (getGeometry() != null) getGeometry().randomVertex(p.getPosition()); p.getPosition().multLocal(getInvScale()); } else { switch (getEmitType()) { case Line: getLine().random(p.getPosition()); break; case Rectangle: getRectangle().random(p.getPosition()); break; case Ring: getRing().random(p.getPosition()); break; case Point: default: p.getPosition().set(originOffset); break; } emitterTransform.multPoint(p.getPosition()); } }
public int compare(Object o1, Object o2) { int a = (Integer) o1; int b = (Integer) o2; if (a == b) { return 0; } Vector3f centerA = null; Vector3f centerB = null; mesh.getTriangle(a, aCompare); mesh.getTriangle(b, bCompare); centerA = aCompare[0].addLocal(aCompare[1].addLocal(aCompare[2])).subtractLocal(center); centerB = bCompare[0].addLocal(bCompare[1].addLocal(bCompare[2])).subtractLocal(center); switch (axis) { case X: if (centerA.x < centerB.x) { return -1; } if (centerA.x > centerB.x) { return 1; } return 0; case Y: if (centerA.y < centerB.y) { return -1; } if (centerA.y > centerB.y) { return 1; } return 0; case Z: if (centerA.z < centerB.z) { return -1; } if (centerA.z > centerB.z) { return 1; } return 0; default: return 0; } }
/** * Nudges an entire object in the given direction through manipulation of its vertices rather than * position of the Spatial itself. * * @param s The Spatial to move. * @param x The amount of x units to move the object. * @param y The amount of y units to move the object. * @param z The amount of z units to move the object. */ public static void adjustObject(Spatial s, float x, float y, float z) { logger.info("Moving " + s.getName() + " " + x + "," + y + "," + z); if (s instanceof TriMesh) { FloatBuffer vb = ((TriMesh) s).getVertexBuffer(); vb.rewind(); float[] floatArray = new float[vb.capacity()]; for (int i = 0; i < ((TriMesh) s).getTriangleCount(); i++) { floatArray[i * 3] = vb.get(i * 3) + x; floatArray[i * 3] = vb.get(i * 3 + 1) + y; floatArray[i * 3] = vb.get(i * 3 + 2) + z; } FloatBuffer newBuffer = FloatBuffer.allocate(vb.capacity()); newBuffer.put(floatArray); ((TriMesh) s).setVertexBuffer(newBuffer); } if (s instanceof QuadMesh) { FloatBuffer vb = ((QuadMesh) s).getVertexBuffer(); vb.rewind(); float[] floatArray = new float[vb.capacity()]; for (int i = 0; i < ((QuadMesh) s).getQuadCount(); i++) { floatArray[i * 4] = vb.get(i * 4) + x; floatArray[i * 4] = vb.get(i * 4 + 1) + y; floatArray[i * 4] = vb.get(i * 4 + 2) + z; } FloatBuffer newBuffer = FloatBuffer.allocate(vb.capacity()); newBuffer.put(floatArray); ((QuadMesh) s).setVertexBuffer(newBuffer); } if (s instanceof Node) { if (((Node) s).getChildren() != null) { for (Spatial child : ((Node) s).getChildren()) { adjustObject(child, x, y, z); } } } }
/** * This is a <b>VERY </b> brute force method of detecting if two TriMesh objects intersect. * * @param mesh1 The first TriMesh. * @param mesh2 The second TriMesh. * @return True if they intersect, false otherwise. */ public static boolean meshIntersection(TriMesh mesh1, TriMesh mesh2) { IntBuffer indexA = mesh1.getIndexBuffer(); IntBuffer indexB = mesh2.getIndexBuffer(); TransformMatrix aTransform = new TransformMatrix(); aTransform.setRotationQuaternion(mesh1.getWorldRotation()); aTransform.setTranslation(mesh1.getWorldTranslation()); aTransform.setScale(mesh1.getWorldScale()); TransformMatrix bTransform = new TransformMatrix(); bTransform.setRotationQuaternion(mesh2.getWorldRotation()); bTransform.setTranslation(mesh2.getWorldTranslation()); bTransform.setScale(mesh2.getWorldScale()); Vector3f[] vertA = BufferUtils.getVector3Array(mesh1.getVertexBuffer()); for (int i = 0; i < vertA.length; i++) aTransform.multPoint(vertA[i]); Vector3f[] vertB = BufferUtils.getVector3Array(mesh2.getVertexBuffer()); for (int i = 0; i < vertB.length; i++) bTransform.multPoint(vertB[i]); for (int i = 0; i < mesh1.getTriangleCount(); i++) { for (int j = 0; j < mesh2.getTriangleCount(); j++) { if (intersection( vertA[indexA.get(i * 3 + 0)], vertA[indexA.get(i * 3 + 1)], vertA[indexA.get(i * 3 + 2)], vertB[indexB.get(j * 3 + 0)], vertB[indexB.get(j * 3 + 1)], vertB[indexB.get(j * 3 + 2)])) return true; } } return false; }