Пример #1
0
  private void readAnimations() throws IOException {
    if (header.ofs_anims == readBytes) {
      for (int i = 0; i < header.num_anims; ++i) {
        byte[] buffer = new byte[ANIM_SIZE];
        readBytes += in.read(buffer);

        int pos = 0;

        AnimationData animData = new AnimationData();

        pos++;
        animData.name = texts.get(textPos++);
        int firstFrame = toInt(buffer, (pos++) * 4);
        int numFrames = toInt(buffer, (pos++) * 4);
        animData.animationFrames = new AnimationFrame[numFrames];
        animData.frameRate = toFloat(buffer, (pos++) * 4);
        animData.flag = toInt(buffer, (pos++) * 4);

        entityData.skeletonData.animations.add(animData);
      }
    }

    if (header.ofs_frames == readBytes) {
      for (int i = 0; i < header.num_anims; ++i) {
        AnimationData animData = entityData.skeletonData.animations.get(i);

        byte[] buffer = new byte[2 * animData.animationFrames.length * header.num_framechannels];
        readBytes += in.read(buffer);

        int pos = 0;
        float prevTime = 0;

        for (int j = 0; j < animData.animationFrames.length; ++j) {
          AnimationFrame frame = new AnimationFrame(header.num_joints);
          animData.animationFrames[j] = frame;
          frame.time = prevTime;
          prevTime += 1 / animData.frameRate;

          for (int k = 0; k < header.num_poses; ++k) {

            PoseData p = entityData.skeletonData.poses[k];
            Vector3 translate =
                new Vector3(p.channeloffset[0], p.channeloffset[1], p.channeloffset[2]);

            if ((p.channelmask & 0x01) != 0)
              translate.x += toShort(buffer, (pos++) * 2) * p.channelscale[0];
            if ((p.channelmask & 0x02) != 0)
              translate.y += toShort(buffer, (pos++) * 2) * p.channelscale[1];
            if ((p.channelmask & 0x04) != 0)
              translate.z += toShort(buffer, (pos++) * 2) * p.channelscale[2];

            Quaternion rotate =
                new Quaternion(
                    p.channeloffset[3], p.channeloffset[4], p.channeloffset[5], p.channeloffset[6]);

            if ((p.channelmask & 0x08) != 0)
              rotate.x += toShort(buffer, (pos++) * 2) * p.channelscale[3];
            if ((p.channelmask & 0x10) != 0)
              rotate.y += toShort(buffer, (pos++) * 2) * p.channelscale[4];
            if ((p.channelmask & 0x20) != 0)
              rotate.z += toShort(buffer, (pos++) * 2) * p.channelscale[5];
            if ((p.channelmask & 0x40) != 0)
              rotate.w += toShort(buffer, (pos++) * 2) * p.channelscale[6];

            if ((p.channelmask & 0x80) != 0) pos++;
            if ((p.channelmask & 0x100) != 0) pos++;
            if ((p.channelmask & 0x200) != 0) pos++;

            frame.bonePos[k] = translate;
            frame.boneRot[k] = rotate;
          }
        }
      }
    }
  }
Пример #2
0
  private void readVertices() throws IOException {

    for (int i = 0; i < header.num_vertexarrays; ++i) {

      VertexArray vertexArray = vertexArrays[i];

      for (int j = 0; j < entityData.subEntities.length; ++j) {
        SubEntityData subEntity = entityData.subEntities[j];
        // These are the vertices belonging to this subentity

        int componentSize = getVertexArrayComponentSize(vertexArray);

        byte[] buffer = new byte[subEntity.countVertices * vertexArray.size * componentSize];
        readBytes += in.read(buffer);

        int pos = 0;
        int byteStride = vertexLayout.getByteStride();
        int offset;

        switch (vertexArray.type) {
          case 0: // This is a position
            offset = vertexLayout.getPos(VertexLayout.POSITION);
            for (int k = 0; k < subEntity.countVertices; ++k) {
              subEntity.vertexData[k * byteStride + offset + 0] = toFloat(buffer, (pos++) * 4);
              subEntity.vertexData[k * byteStride + offset + 1] = toFloat(buffer, (pos++) * 4);
              subEntity.vertexData[k * byteStride + offset + 2] = toFloat(buffer, (pos++) * 4);
            }

            break;
          case 1: // This is a texture coordinate
            offset = vertexLayout.getPos(VertexLayout.UV);
            for (int k = 0; k < subEntity.countVertices; ++k) {
              subEntity.vertexData[k * byteStride + offset + 0] = toFloat(buffer, (pos++) * 4);
              subEntity.vertexData[k * byteStride + offset + 1] = toFloat(buffer, (pos++) * 4);
            }

            break;
          case 2: // This is a normal
            offset = vertexLayout.getPos(VertexLayout.NORMAL);
            for (int k = 0; k < subEntity.countVertices; ++k) {
              float x = toFloat(buffer, (pos++) * 4);
              float y = toFloat(buffer, (pos++) * 4);
              float z = toFloat(buffer, (pos++) * 4);

              if (light == null) {
                // Lighting information not baked into the mesh
                subEntity.vertexData[k * byteStride + offset + 0] = x;
                subEntity.vertexData[k * byteStride + offset + 1] = y;
                subEntity.vertexData[k * byteStride + offset + 2] = z;
              } else {
                // Lighting information baked into the mesh
                float[] lightVector = light.getLightVector();
                float diffuse =
                    Math.max(
                        Vector3.dot(x, y, z, lightVector[0], lightVector[1], lightVector[2]), 0);
                subEntity.vertexData[k * byteStride + offset] = diffuse;
              }
            }
            break;
          case 4: // This is a blendindex
            offset = Mesh.BONE_INDEX_OFFSET;
            for (int k = 0; k < subEntity.countVertices; ++k) {
              for (int m = 0; m < 4; ++m) {
                int intVal = buffer[pos++] & 0xff;
                subEntity.boneData[k * Mesh.BONE_BYTE_STRIDE + offset + m] = intVal;
              }
            }
            break;
          case 5: // This is a blendweight
            offset = Mesh.BONE_WEIGHT_OFFSET;
            for (int k = 0; k < subEntity.countVertices; ++k) {
              for (int m = 0; m < 4; ++m) {
                int intVal = buffer[pos++] & 0xff;
                float weight = intVal / 255.f;
                subEntity.boneData[k * Mesh.BONE_BYTE_STRIDE + offset + m] = weight;
              }
            }
            break;
          case 6: // This i a color
            break;
          default: // None of the above, we dont care about this data;
            break;
        }
      }
    }
  }