private void readSubEntities() throws IOException { entityData.subEntities = new SubEntityData[header.num_meshes]; for (int i = 0; i < header.num_meshes; ++i) { // create all subentities SubEntityData subEntity = new SubEntityData(); byte[] buffer = new byte[SUBENTITY_SIZE]; readBytes += in.read(buffer); int pos = 0; pos++; pos++; int firstVertex = toInt(buffer, (pos++) * 4); int numVertices = toInt(buffer, (pos++) * 4); int firstTriangle = toInt(buffer, (pos++) * 4); int numTriangles = toInt(buffer, (pos++) * 4); subEntity.name = texts.get(textPos++); subEntity.material = texts.get(textPos++); subEntity.firstTriangleIndex = firstTriangle; subEntity.firstVertexIndex = firstVertex; subEntity.countTriangles = numTriangles; subEntity.countVertices = numVertices; subEntity.vertexData = new float[numVertices * vertexLayout.getByteStride()]; subEntity.triangleData = new short[numTriangles * 3]; subEntity.boneData = new float[numVertices * Mesh.BONE_BYTE_STRIDE]; entityData.subEntities[i] = subEntity; } }
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; } } } }