Example #1
0
  public SkySphere(Vector3 position, float scale, Texture texture) {

    this.scale = scale;
    this.position = position;
    this.mTexture = texture;

    VertexBufferDeclaration vbd = new VertexBufferDeclaration();
    vbd.add(
        new VertexBufferDefinition(
            VertexBufferDefinition.FLOAT,
            VertexBufferDefinition.DEF_VERTEX,
            3,
            VertexBufferDefinition.ACCESS_DYNAMIC));
    vbd.add(
        new VertexBufferDefinition(
            VertexBufferDefinition.FLOAT,
            VertexBufferDefinition.DEF_TEXTURE_COORD,
            2,
            VertexBufferDefinition.ACCESS_DYNAMIC));
    vbd.add(
        new VertexBufferDefinition(
            VertexBufferDefinition.FLOAT,
            VertexBufferDefinition.DEF_NORMAL,
            3,
            VertexBufferDefinition.ACCESS_DYNAMIC));

    mVertexBuffer = new VertexBuffer(128, vbd);
    mIndexBuffer = new IndexBufferShort(GLES20.GL_TRIANGLES, 256 * 3);

    mIndexBuffer.put(indexdata);

    mVertexBuffer.getBuffer(0).put(vertexdata);
    mVertexBuffer.getBuffer(1).put(stdata);
    mVertexBuffer.getBuffer(2).put(normaldata);
  }
Example #2
0
  private void renderLines() {
    if (phenixLineProgram != null) {
      if (!phenixLineProgram.use()) {
        return;
      }

      float angle =
          360.0f * getTimeDeltaByScale((long) (1 * 50000L / speedFactor / rotationSpeedFactor));
      Matrix.setRotateM(M_matrix, 0, angle, 0, 0, 1.0f);

      Matrix.multiplyMM(MVP_matrix, 0, V_matrix, 0, M_matrix, 0);
      Matrix.multiplyMM(MVP_matrix, 0, P_matrix, 0, MVP_matrix, 0);

      float delta = getTimeDeltaByScale((long) (1 * 25000L / speedFactor));

      lineVertices.bind(phenixLineProgram, "aPosition", null);

      GLES20.glUniformMatrix4fv(
          phenixLineProgram.getUniformLocation("uMVPMatrix"), 1, false, MVP_matrix, 0);

      GLES20.glUniform1f(phenixLineProgram.getUniformLocation("uDelta"), delta);
      GLES20.glUniform1f(
          phenixLineProgram.getUniformLocation("uBrightness"), brightness * brightnessFactor);
      GLES20.glUniform3f(
          phenixLineProgram.getUniformLocation("uColor"),
          linesColorRed,
          linesColorGreen,
          linesColorBlue);

      GLES20.glEnable(GLES20.GL_BLEND);
      GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
      GLES20.glLineWidth(lineWidth * lineWidthFactor);

      lineVertices.draw(GLES20.GL_LINES, 0, MOVING_LINE_COUNT);

      GLES20.glUniform1f(phenixLineProgram.getUniformLocation("uDelta"), 0.0f);

      lineVertices.draw(GLES20.GL_LINES, MOVING_LINE_COUNT, STALE_LINE_COUNT);

      GLES20.glDisable(GLES20.GL_BLEND);

      lineVertices.unbind(phenixLineProgram, "aPosition", null);
    }
  }
Example #3
0
  private void renderBlurTexture(int textureIndex) {
    if (postProgram.use()) {
      renderTextures[textureIndex].bind(GLES20.GL_TEXTURE0, postProgram, "sTexture");
      quadVertices.bind(postProgram, "aPosition", "aTextureCoord");

      GLES20.glUniform1f(postProgram.getUniformLocation("uBlur"), blur * blurFactor);

      GLES20.glUniformMatrix4fv(
          postProgram.getUniformLocation("uMVPMatrix"), 1, false, Q_matrix, 0);

      GLES20.glEnable(GLES20.GL_BLEND);
      GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);

      quadVertices.draw(GLES20.GL_TRIANGLE_STRIP);

      GLES20.glDisable(GLES20.GL_BLEND);

      quadVertices.unbind(postProgram, "aPosition", "aTextureCoord");

      renderTextures[textureIndex].unbind(GLES20.GL_TEXTURE0);
    }
  }
Example #4
0
  public void Draw() {
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.getID());
    GLES20.glDisable(GLES20.GL_DEPTH_TEST);
    // GLES20.glDisable(GLES20.GL_CULL_FACE);
    // GLES20.glDisable(GLES20.GL_LIGHTING);
    // GLES20.glPushMatrix();
    // GLES20.glTranslatef(position.X, position.Y, position.Z);
    Renderer.pushModelViewMatrix();
    Renderer.modelview.translate(position.X, position.Y, position.Z);
    // GLES20.glScalef(scale, scale, scale);
    Renderer.modelview.scale(scale, scale, scale);
    Renderer.loadModelViewMatrix();

    mVertexBuffer.Draw(mIndexBuffer);
    // GLES20.glPopMatrix();
    Renderer.popModelViewMatrix();
    Renderer.loadModelViewMatrix();
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    // GLES20.glEnable(GLES20.GL_CULL_FACE);
    // GLES20.glEnable(GLES20.GL_LIGHTING);
  }
Example #5
0
  private static AttributeData[] createAttributeData(VertexBuffer vbuffer) {
    List<AttributeData> attribute = new ArrayList<>();
    for (Element el : vbuffer.layout.getElements()) {
      if (el.equals(POSITION) || el.equals(NORMAL) || el.equals(TEX_COORD)) {
        continue;
      }

      if (el.getDataType() != FLOAT
          || el.getVectorType().getElementCount() > CTM_ATTR_ELEMENT_COUNT) {
        logger.warn(
            "The mesh-attribute "
                + el.toString()
                + " can't be exported to the ctm format! Only float "
                + "attributes with max. 4 elements are supported.");
        continue;
      }

      float[] values = new float[vbuffer.getVcount() * CTM_ATTR_ELEMENT_COUNT];

      {
        int k = 0;
        for (Vertex v : vbuffer) {
          copyToBuffer(values, k, v, el);
          k += CTM_ATTR_ELEMENT_COUNT;
        }
      }

      attribute.add(
          new AttributeData(el.getBezeichnung(), null, AttributeData.STANDARD_PRECISION, values));
    }

    AttributeData[] atts = new AttributeData[attribute.size()];
    attribute.toArray(atts);

    return atts;
  }
Example #6
0
  public static Object3D[] load(byte[] data, int offset) {
    DataInputStream old = dis;
    dis = new DataInputStream(new ByteArrayInputStream(data));

    try {
      while (dis.available() > 0) {
        int objectType = readByte();
        int length = readInt();

        System.out.println("objectType: " + objectType);
        System.out.println("length: " + length);

        dis.mark(Integer.MAX_VALUE);

        if (objectType == 0) {
          int versionHigh = readByte();
          int versionLow = readByte();
          boolean hasExternalReferences = readBoolean();
          int totolFileSize = readInt();
          int approximateContentSize = readInt();
          String authoringField = readString();

          objs.addElement(new Group()); // dummy
        } else if (objectType == 255) {
          // TODO: load external resource
          System.out.println("Loader: Loading external resources not implemented.");
          String uri = readString();
        } else if (objectType == 1) {
          System.out.println("Loader: AnimationController not implemented.");
          objs.addElement(new Group()); // dummy
        } else if (objectType == 2) {
          System.out.println("Loader: AnimationTrack not implemented.");
          objs.addElement(new Group()); // dummy
        } else if (objectType == 3) {
          // System.out.println("Appearance");
          Appearance appearance = new Appearance();
          loadObject3D(appearance);
          appearance.setLayer(readByte());
          appearance.setCompositingMode((CompositingMode) getObject(readInt()));
          appearance.setFog((Fog) getObject(readInt()));
          appearance.setPolygonMode((PolygonMode) getObject(readInt()));
          appearance.setMaterial((Material) getObject(readInt()));
          int numTextures = readInt();
          for (int i = 0; i < numTextures; ++i)
            appearance.setTexture(i, (Texture2D) getObject(readInt()));
          objs.addElement(appearance);
        } else if (objectType == 4) {
          // System.out.println("Background");
          Background background = new Background();
          loadObject3D(background);
          background.setColor(readRGBA());
          background.setImage((Image2D) getObject(readInt()));
          int modeX = readByte();
          int modeY = readByte();
          background.setImageMode(modeX, modeY);
          int cropX = readInt();
          int cropY = readInt();
          int cropWidth = readInt();
          int cropHeight = readInt();
          background.setCrop(cropX, cropY, cropWidth, cropHeight);
          background.setDepthClearEnable(readBoolean());
          background.setColorClearEnable(readBoolean());
          objs.addElement(background); // dummy
        } else if (objectType == 5) {
          // System.out.println("Camera");

          Camera camera = new Camera();
          loadNode(camera);

          int projectionType = readByte();
          if (projectionType == Camera.GENERIC) {
            Transform t = new Transform();
            t.set(readMatrix());
            camera.setGeneric(t);
          } else {
            float fovy = readFloat();
            float aspect = readFloat();
            float near = readFloat();
            float far = readFloat();
            if (projectionType == Camera.PARALLEL) camera.setParallel(fovy, aspect, near, far);
            else camera.setPerspective(fovy, aspect, near, far);
          }
          objs.addElement(camera);
        } else if (objectType == 6) {
          // System.out.println("CompositingMode");
          CompositingMode compositingMode = new CompositingMode();
          loadObject3D(compositingMode);
          compositingMode.setDepthTestEnabled(readBoolean());
          compositingMode.setDepthWriteEnabled(readBoolean());
          compositingMode.setColorWriteEnabled(readBoolean());
          compositingMode.setAlphaWriteEnabled(readBoolean());
          compositingMode.setBlending(readByte());
          compositingMode.setAlphaThreshold((float) readByte() / 255.0f);
          compositingMode.setDepthOffsetFactor(readFloat());
          compositingMode.setDepthOffsetUnits(readFloat());
          objs.addElement(compositingMode);
        } else if (objectType == 7) {
          // System.out.println("Fog");
          Fog fog = new Fog();
          loadObject3D(fog);
          fog.setColor(readRGB());
          fog.setMode(readByte());
          if (fog.getMode() == Fog.EXPONENTIAL) fog.setDensity(readFloat());
          else {
            fog.setNearDistance(readFloat());
            fog.setFarDistance(readFloat());
          }
          objs.addElement(fog);
        } else if (objectType == 9) {
          // System.out.println("Group");
          Group group = new Group();
          loadGroup(group);
          objs.addElement(group);
        } else if (objectType == 10) {
          // System.out.println("Image2D");
          Image2D image = null;
          loadObject3D(new Group()); // dummy
          int format = readByte();
          boolean isMutable = readBoolean();
          int width = readInt();
          int height = readInt();
          if (!isMutable) {
            // Read palette
            int paletteSize = readInt();
            byte[] palette = null;
            if (paletteSize > 0) {
              palette = new byte[paletteSize];
              dis.readFully(palette);
            }
            // Read pixels
            int pixelSize = readInt();
            byte[] pixel = new byte[pixelSize];
            dis.readFully(pixel);
            // Create image
            if (palette != null) image = new Image2D(format, width, height, pixel, palette);
            else image = new Image2D(format, width, height, pixel);
          } else image = new Image2D(format, width, height);

          dis.reset();
          loadObject3D(image);

          objs.addElement(image);
        } else if (objectType == 19) {
          System.out.println("Loader: KeyframeSequence not implemented.");
          /*
          Byte          interpolation;
          Byte          repeatMode;
          Byte          encoding;
          UInt32        duration;
          UInt32        validRangeFirst;
          UInt32        validRangeLast;

          UInt32        componentCount;
          UInt32        keyframeCount;

          IF encoding == 0

          FOR each key frame...

          UInt32                  time;
          Float32[componentCount] vectorValue;

          END

          ELSE IF encoding == 1

          Float32[componentCount] vectorBias;
          Float32[componentCount] vectorScale;

          FOR each key frame...

          UInt32               time;
          Byte[componentCount] vectorValue;

          END

          ELSE IF encoding == 2

          Float32[componentCount] vectorBias;
          Float32[componentCount] vectorScale;

          FOR each key frame...

          UInt32                 time;
          UInt16[componentCount] vectorValue;

          END

          END
          */
          objs.addElement(new Group()); // dummy
        } else if (objectType == 12) {
          // System.out.println("Light");
          Light light = new Light();
          loadNode(light);
          float constant = readFloat();
          float linear = readFloat();
          float quadratic = readFloat();
          light.setAttenuation(constant, linear, quadratic);
          light.setColor(readRGB());
          light.setMode(readByte());
          light.setIntensity(readFloat());
          light.setSpotAngle(readFloat());
          light.setSpotExponent(readFloat());
          objs.addElement(light);
        } else if (objectType == 13) {
          // System.out.println("Material");
          Material material = new Material();
          loadObject3D(material);
          material.setColor(Material.AMBIENT, readRGB());
          material.setColor(Material.DIFFUSE, readRGBA());
          material.setColor(Material.EMISSIVE, readRGB());
          material.setColor(Material.SPECULAR, readRGB());
          material.setShininess(readFloat());
          material.setVertexColorTrackingEnable(readBoolean());
          objs.addElement(material);
        } else if (objectType == 14) {
          // System.out.println("Mesh");

          loadNode(new Group()); // dummy

          VertexBuffer vertices = (VertexBuffer) getObject(readInt());
          int submeshCount = readInt();

          IndexBuffer[] submeshes = new IndexBuffer[submeshCount];
          Appearance[] appearances = new Appearance[submeshCount];
          for (int i = 0; i < submeshCount; ++i) {
            submeshes[i] = (IndexBuffer) getObject(readInt());
            appearances[i] = (Appearance) getObject(readInt());
          }
          Mesh mesh = new Mesh(vertices, submeshes, appearances);

          dis.reset();
          loadNode(mesh);

          objs.addElement(mesh);
        } else if (objectType == 15) {
          System.out.println("Loader: MorphingMesh not implemented.");
          /*
          UInt32        morphTargetCount;

          FOR each target buffer...

          ObjectIndex   morphTarget;
          Float32       initialWeight;

          END
          */
          objs.addElement(new Group()); // dummy
        } else if (objectType == 8) {
          // System.out.println("PolygonMode");
          PolygonMode polygonMode = new PolygonMode();
          loadObject3D(polygonMode);
          polygonMode.setCulling(readByte());
          polygonMode.setShading(readByte());
          polygonMode.setWinding(readByte());
          polygonMode.setTwoSidedLightingEnable(readBoolean());
          polygonMode.setLocalCameraLightingEnable(readBoolean());
          polygonMode.setPerspectiveCorrectionEnable(readBoolean());
          objs.addElement(polygonMode);
        } else if (objectType == 16) {
          System.out.println("Loader: SkinnedMesh not implemented.");
          /*
          ObjectIndex   skeleton;

          UInt32        transformReferenceCount;

          FOR each bone reference...

          ObjectIndex   transformNode;
          UInt32        firstVertex;
          UInt32        vertexCount;
          Int32         weight;

          END
          */
          objs.addElement(new Group()); // dummy
        } else if (objectType == 18) {
          System.out.println("Loader: Sprite not implemented.");
          /*
          ObjectIndex   image;
          ObjectIndex   appearance;

          Boolean       isScaled;

          Int32         cropX;
          Int32         cropY;
          Int32         cropWidth;
          Int32         cropHeight;
          */
          objs.addElement(new Group()); // dummy
        } else if (objectType == 17) {
          // System.out.println("Texture2D");

          loadTransformable(new Group()); // dummy

          Texture2D texture = new Texture2D((Image2D) getObject(readInt()));
          texture.setBlendColor(readRGB());
          texture.setBlending(readByte());
          int wrapS = readByte();
          int wrapT = readByte();
          texture.setWrapping(wrapS, wrapT);
          int levelFilter = readByte();
          int imageFilter = readByte();
          texture.setFiltering(levelFilter, imageFilter);

          dis.reset();
          loadTransformable(texture);

          objs.addElement(texture);
        } else if (objectType == 11) {
          // System.out.println("TriangleStripArray");

          loadObject3D(new Group()); // dummy

          int encoding = readByte();
          int firstIndex = 0;
          int[] indices = null;
          if (encoding == 0) firstIndex = readInt();
          else if (encoding == 1) firstIndex = readByte();
          else if (encoding == 2) firstIndex = readShort();
          else if (encoding == 128) {
            int numIndices = readInt();
            indices = new int[numIndices];
            for (int i = 0; i < numIndices; ++i) indices[i] = readInt();
          } else if (encoding == 129) {
            int numIndices = readInt();
            indices = new int[numIndices];
            for (int i = 0; i < numIndices; ++i) indices[i] = readByte();
          } else if (encoding == 130) {
            int numIndices = readInt();
            indices = new int[numIndices];
            for (int i = 0; i < numIndices; ++i) indices[i] = readShort();
          }

          int numStripLengths = readInt();
          int[] stripLengths = new int[numStripLengths];
          for (int i = 0; i < numStripLengths; ++i) stripLengths[i] = readInt();

          dis.reset();

          TriangleStripArray triStrip = null;
          if (indices == null) triStrip = new TriangleStripArray(firstIndex, stripLengths);
          else triStrip = new TriangleStripArray(indices, stripLengths);

          loadObject3D(triStrip);

          objs.addElement(triStrip);
        } else if (objectType == 20) {
          // System.out.println("VertexArray");

          loadObject3D(new Group()); // dummy

          int componentSize = readByte();
          int componentCount = readByte();
          int encoding = readByte();
          int vertexCount = readShort();

          VertexArray vertices = new VertexArray(vertexCount, componentCount, componentSize);

          if (componentSize == 1) {
            byte[] values = new byte[componentCount * vertexCount];
            if (encoding == 0) dis.readFully(values);
            else {
              byte last = 0;
              for (int i = 0; i < vertexCount * componentCount; ++i) {
                last += readByte();
                values[i] = last;
              }
            }
            vertices.set(0, vertexCount, values);
          } else {
            short last = 0;
            short[] values = new short[componentCount * vertexCount];
            for (int i = 0; i < componentCount * vertexCount; ++i) {
              if (encoding == 0) values[i] = (short) readShort();
              else {
                last += (short) readShort();
                values[i] = last;
              }
            }
            vertices.set(0, vertexCount, values);
          }

          dis.reset();
          loadObject3D(vertices);

          objs.addElement(vertices);
        } else if (objectType == 21) {
          // System.out.println("VertexBuffer");

          VertexBuffer vertices = new VertexBuffer();
          loadObject3D(vertices);

          vertices.setDefaultColor(readRGBA());

          VertexArray positions = (VertexArray) getObject(readInt());
          float[] bias = new float[3];
          bias[0] = readFloat();
          bias[1] = readFloat();
          bias[2] = readFloat();
          float scale = readFloat();
          vertices.setPositions(positions, scale, bias);

          vertices.setNormals((VertexArray) getObject(readInt()));
          vertices.setColors((VertexArray) getObject(readInt()));

          int texCoordArrayCount = readInt();
          for (int i = 0; i < texCoordArrayCount; ++i) {
            VertexArray texcoords = (VertexArray) getObject(readInt());
            bias[0] = readFloat();
            bias[1] = readFloat();
            bias[2] = readFloat();
            scale = readFloat();
            vertices.setTexCoords(i, texcoords, scale, bias);
          }

          objs.addElement(vertices);
        } else if (objectType == 22) {
          // System.out.println("World");

          World world = new World();
          loadGroup(world);

          world.setActiveCamera((Camera) getObject(readInt()));
          world.setBackground((Background) getObject(readInt()));
          objs.addElement(world);
        } else {
          System.out.println("Loader: unsupported objectType " + objectType + ".");
        }

        dis.reset();
        dis.skipBytes(length);
      }
    } catch (Exception e) {
      System.out.println("Exception: " + e.getMessage());
      e.printStackTrace();
    }

    dis = old;
    return null;
  }
Example #7
0
  /**
   * Merges all geometries in the collection into the output mesh. Does not take into account
   * materials.
   *
   * @param geometries
   * @param outMesh
   */
  private void mergeGeometries(Mesh outMesh, List<Geometry> geometries) {
    int[] compsForBuf = new int[VertexBuffer.Type.values().length];
    VertexBuffer.Format[] formatForBuf = new VertexBuffer.Format[compsForBuf.length];

    int totalVerts = 0;
    int totalTris = 0;
    int totalLodLevels = 0;
    int maxWeights = -1;

    Mesh.Mode mode = null;
    for (Geometry geom : geometries) {
      totalVerts += geom.getVertexCount();
      totalTris += geom.getTriangleCount();
      totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
      if (maxVertCount < geom.getVertexCount()) {
        maxVertCount = geom.getVertexCount();
      }
      Mesh.Mode listMode;
      int components;
      switch (geom.getMesh().getMode()) {
        case Points:
          listMode = Mesh.Mode.Points;
          components = 1;
          break;
        case LineLoop:
        case LineStrip:
        case Lines:
          listMode = Mesh.Mode.Lines;
          components = 2;
          break;
        case TriangleFan:
        case TriangleStrip:
        case Triangles:
          listMode = Mesh.Mode.Triangles;
          components = 3;
          break;
        default:
          throw new UnsupportedOperationException();
      }

      for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
        compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
        formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
      }

      maxWeights = Math.max(maxWeights, geom.getMesh().getMaxNumWeights());

      if (mode != null && mode != listMode) {
        throw new UnsupportedOperationException(
            "Cannot combine different" + " primitive types: " + mode + " != " + listMode);
      }
      mode = listMode;
      compsForBuf[VertexBuffer.Type.Index.ordinal()] = components;
    }

    outMesh.setMaxNumWeights(maxWeights);
    outMesh.setMode(mode);
    if (totalVerts >= 65536) {
      // make sure we create an UnsignedInt buffer so
      // we can fit all of the meshes
      formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt;
    } else {
      formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort;
    }

    // generate output buffers based on retrieved info
    for (int i = 0; i < compsForBuf.length; i++) {
      if (compsForBuf[i] == 0) {
        continue;
      }

      Buffer data;
      if (i == VertexBuffer.Type.Index.ordinal()) {
        data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
      } else {
        data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
      }

      VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.values()[i]);
      vb.setupData(VertexBuffer.Usage.Dynamic, compsForBuf[i], formatForBuf[i], data);
      outMesh.setBuffer(vb);
    }

    int globalVertIndex = 0;
    int globalTriIndex = 0;

    for (Geometry geom : geometries) {
      Mesh inMesh = geom.getMesh();
      if (!isBatch(geom)) {
        geom.batch(this, globalVertIndex);
      }

      int geomVertCount = inMesh.getVertexCount();
      int geomTriCount = inMesh.getTriangleCount();

      for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
        VertexBuffer inBuf = inMesh.getBuffer(VertexBuffer.Type.values()[bufType]);

        VertexBuffer outBuf = outMesh.getBuffer(VertexBuffer.Type.values()[bufType]);

        if (outBuf == null) {
          continue;
        }

        if (VertexBuffer.Type.Index.ordinal() == bufType) {
          int components = compsForBuf[bufType];

          IndexBuffer inIdx = inMesh.getIndicesAsList();
          IndexBuffer outIdx = outMesh.getIndexBuffer();

          for (int tri = 0; tri < geomTriCount; tri++) {
            for (int comp = 0; comp < components; comp++) {
              int idx = inIdx.get(tri * components + comp) + globalVertIndex;
              outIdx.put((globalTriIndex + tri) * components + comp, idx);
            }
          }
        } else if (VertexBuffer.Type.Position.ordinal() == bufType) {
          FloatBuffer inPos = (FloatBuffer) inBuf.getData();
          FloatBuffer outPos = (FloatBuffer) outBuf.getData();
          doCopyBuffer(inPos, globalVertIndex, outPos, 3);
        } else if (VertexBuffer.Type.Normal.ordinal() == bufType
            || VertexBuffer.Type.Tangent.ordinal() == bufType) {
          FloatBuffer inPos = (FloatBuffer) inBuf.getData();
          FloatBuffer outPos = (FloatBuffer) outBuf.getData();
          doCopyBuffer(inPos, globalVertIndex, outPos, compsForBuf[bufType]);
          if (VertexBuffer.Type.Tangent.ordinal() == bufType) {
            useTangents = true;
          }
        } else {
          inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
          //                    for (int vert = 0; vert < geomVertCount; vert++) {
          //                        int curGlobalVertIndex = globalVertIndex + vert;
          //                        inBuf.copyElement(vert, outBuf, curGlobalVertIndex);
          //                    }
        }
      }

      globalVertIndex += geomVertCount;
      globalTriIndex += geomTriCount;
    }
  }
Example #8
0
  protected void updateSubBatch(Geometry bg) {
    Batch batch = batchesByGeom.get(bg);
    if (batch != null) {
      Mesh mesh = batch.geometry.getMesh();
      Mesh origMesh = bg.getMesh();

      VertexBuffer pvb = mesh.getBuffer(VertexBuffer.Type.Position);
      FloatBuffer posBuf = (FloatBuffer) pvb.getData();
      VertexBuffer nvb = mesh.getBuffer(VertexBuffer.Type.Normal);
      FloatBuffer normBuf = (FloatBuffer) nvb.getData();

      VertexBuffer opvb = origMesh.getBuffer(VertexBuffer.Type.Position);
      FloatBuffer oposBuf = (FloatBuffer) opvb.getData();
      VertexBuffer onvb = origMesh.getBuffer(VertexBuffer.Type.Normal);
      FloatBuffer onormBuf = (FloatBuffer) onvb.getData();
      Matrix4f transformMat = getTransformMatrix(bg);

      if (mesh.getBuffer(VertexBuffer.Type.Tangent) != null) {

        VertexBuffer tvb = mesh.getBuffer(VertexBuffer.Type.Tangent);
        FloatBuffer tanBuf = (FloatBuffer) tvb.getData();
        VertexBuffer otvb = origMesh.getBuffer(VertexBuffer.Type.Tangent);
        FloatBuffer otanBuf = (FloatBuffer) otvb.getData();
        doTransformsTangents(
            oposBuf,
            onormBuf,
            otanBuf,
            posBuf,
            normBuf,
            tanBuf,
            bg.startIndex,
            bg.startIndex + bg.getVertexCount(),
            transformMat);
        tvb.updateData(tanBuf);
      } else {
        doTransforms(
            oposBuf,
            onormBuf,
            posBuf,
            normBuf,
            bg.startIndex,
            bg.startIndex + bg.getVertexCount(),
            transformMat);
      }
      pvb.updateData(posBuf);
      nvb.updateData(normBuf);

      batch.needMeshUpdate = true;
    }
  }
Example #9
0
  /**
   * Specific method for skinning with tangents to avoid cluttering the classic skinning calculation
   * with null checks that would slow down the process even if tangents don't have to be computed.
   * Also the iteration has additional indexes since tangent has 4 components instead of 3 for pos
   * and norm
   *
   * @param maxWeightsPerVert maximum number of weights per vertex
   * @param mesh the mesh
   * @param offsetMatrices the offsetMaytrices to apply
   * @param tb the tangent vertexBuffer
   */
  private void applySkinningTangents(Mesh mesh, Matrix4f[] offsetMatrices, VertexBuffer tb) {
    int maxWeightsPerVert = mesh.getMaxNumWeights();

    if (maxWeightsPerVert <= 0) {
      throw new IllegalStateException("Max weights per vert is incorrectly set!");
    }

    int fourMinusMaxWeights = 4 - maxWeightsPerVert;

    // NOTE: This code assumes the vertex buffer is in bind pose
    // resetToBind() has been called this frame
    VertexBuffer vb = mesh.getBuffer(Type.Position);
    FloatBuffer fvb = (FloatBuffer) vb.getData();
    fvb.rewind();

    VertexBuffer nb = mesh.getBuffer(Type.Normal);

    FloatBuffer fnb = (FloatBuffer) nb.getData();
    fnb.rewind();

    FloatBuffer ftb = (FloatBuffer) tb.getData();
    ftb.rewind();

    // get boneIndexes and weights for mesh
    ByteBuffer ib = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();

    ib.rewind();
    wb.rewind();

    float[] weights = wb.array();
    byte[] indices = ib.array();
    int idxWeights = 0;

    TempVars vars = TempVars.get();

    float[] posBuf = vars.skinPositions;
    float[] normBuf = vars.skinNormals;
    float[] tanBuf = vars.skinTangents;

    int iterations = (int) FastMath.ceil(fvb.capacity() / ((float) posBuf.length));
    int bufLength = 0;
    int tanLength = 0;
    for (int i = iterations - 1; i >= 0; i--) {
      // read next set of positions and normals from native buffer
      bufLength = Math.min(posBuf.length, fvb.remaining());
      tanLength = Math.min(tanBuf.length, ftb.remaining());
      fvb.get(posBuf, 0, bufLength);
      fnb.get(normBuf, 0, bufLength);
      ftb.get(tanBuf, 0, tanLength);
      int verts = bufLength / 3;
      int idxPositions = 0;
      // tangents has their own index because of the 4 components
      int idxTangents = 0;

      // iterate vertices and apply skinning transform for each effecting bone
      for (int vert = verts - 1; vert >= 0; vert--) {
        float nmx = normBuf[idxPositions];
        float vtx = posBuf[idxPositions++];
        float nmy = normBuf[idxPositions];
        float vty = posBuf[idxPositions++];
        float nmz = normBuf[idxPositions];
        float vtz = posBuf[idxPositions++];

        float tnx = tanBuf[idxTangents++];
        float tny = tanBuf[idxTangents++];
        float tnz = tanBuf[idxTangents++];

        // skipping the 4th component of the tangent since it doesn't have to be transformed
        idxTangents++;

        float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0, rtx = 0, rty = 0, rtz = 0;

        for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
          float weight = weights[idxWeights];
          Matrix4f mat = offsetMatrices[indices[idxWeights++]];

          rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
          ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
          rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;

          rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
          rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
          rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;

          rtx += (tnx * mat.m00 + tny * mat.m01 + tnz * mat.m02) * weight;
          rty += (tnx * mat.m10 + tny * mat.m11 + tnz * mat.m12) * weight;
          rtz += (tnx * mat.m20 + tny * mat.m21 + tnz * mat.m22) * weight;
        }

        idxWeights += fourMinusMaxWeights;

        idxPositions -= 3;

        normBuf[idxPositions] = rnx;
        posBuf[idxPositions++] = rx;
        normBuf[idxPositions] = rny;
        posBuf[idxPositions++] = ry;
        normBuf[idxPositions] = rnz;
        posBuf[idxPositions++] = rz;

        idxTangents -= 4;

        tanBuf[idxTangents++] = rtx;
        tanBuf[idxTangents++] = rty;
        tanBuf[idxTangents++] = rtz;

        // once again skipping the 4th component of the tangent
        idxTangents++;
      }

      fvb.position(fvb.position() - bufLength);
      fvb.put(posBuf, 0, bufLength);
      fnb.position(fnb.position() - bufLength);
      fnb.put(normBuf, 0, bufLength);
      ftb.position(ftb.position() - tanLength);
      ftb.put(tanBuf, 0, tanLength);
    }

    vars.release();

    vb.updateData(fvb);
    nb.updateData(fnb);
    tb.updateData(ftb);
  }
Example #10
0
  void resetToBind() {
    for (Mesh mesh : targets) {
      if (isMeshAnimated(mesh)) {
        FloatBuffer bwBuff = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
        ByteBuffer biBuff = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
        if (!biBuff.hasArray() || !bwBuff.hasArray()) {
          mesh.prepareForAnim(true); // prepare for software animation
        }
        VertexBuffer bindPos = mesh.getBuffer(Type.BindPosePosition);
        VertexBuffer bindNorm = mesh.getBuffer(Type.BindPoseNormal);
        VertexBuffer pos = mesh.getBuffer(Type.Position);
        VertexBuffer norm = mesh.getBuffer(Type.Normal);
        FloatBuffer pb = (FloatBuffer) pos.getData();
        FloatBuffer nb = (FloatBuffer) norm.getData();
        FloatBuffer bpb = (FloatBuffer) bindPos.getData();
        FloatBuffer bnb = (FloatBuffer) bindNorm.getData();
        pb.clear();
        nb.clear();
        bpb.clear();
        bnb.clear();

        // reseting bind tangents if there is a bind tangent buffer
        VertexBuffer bindTangents = mesh.getBuffer(Type.BindPoseTangent);
        if (bindTangents != null) {
          VertexBuffer tangents = mesh.getBuffer(Type.Tangent);
          FloatBuffer tb = (FloatBuffer) tangents.getData();
          FloatBuffer btb = (FloatBuffer) bindTangents.getData();
          tb.clear();
          btb.clear();
          tb.put(btb).clear();
        }

        pb.put(bpb).clear();
        nb.put(bnb).clear();
      }
    }
  }