/** {@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;
  }
Example #2
0
 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;
 }
Example #3
0
 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);
 }
Example #4
0
 @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);
 }
Example #5
0
 @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;
  }