Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1051 | chris | 1 | package com.gebauz.bauzoid.graphics.model; |
| 2 | |||
| 3 | import java.io.IOException; |
||
| 4 | |||
| 5 | import com.badlogic.gdx.Gdx; |
||
| 6 | import com.badlogic.gdx.files.FileHandle; |
||
| 7 | import com.badlogic.gdx.graphics.Texture; |
||
| 8 | import com.gebauz.bauzoid.app.Consts; |
||
| 9 | import com.gebauz.bauzoid.file.File; |
||
| 10 | import com.gebauz.bauzoid.graphics.Graphics; |
||
| 11 | import com.gebauz.bauzoid.graphics.model.Mesh; |
||
| 12 | import com.gebauz.bauzoid.graphics.renderstates.RenderStatesConfiguration; |
||
| 13 | import com.gebauz.bauzoid.graphics.shader.Effect; |
||
| 14 | import com.gebauz.bauzoid.graphics.shader.ShaderProgram; |
||
| 15 | import com.gebauz.bauzoid.graphics.shader.ShaderUtil; |
||
| 16 | import com.gebauz.bauzoid.graphics.shader.Technique; |
||
| 17 | import com.gebauz.bauzoid.math.BoundingBox; |
||
| 18 | import com.gebauz.bauzoid.math.Matrix4; |
||
| 19 | import com.gebauz.bauzoid.math.Vector2; |
||
| 20 | import com.gebauz.bauzoid.math.Vector3; |
||
| 21 | import com.gebauz.bauzoid.math.Vector4; |
||
| 22 | |||
| 23 | public class ModelUtil |
||
| 24 | { |
||
| 25 | public static final String LOG_TAG = Consts.LOG_TAG + ":ModelUtil"; |
||
| 26 | public static boolean verbose = false; |
||
| 27 | |||
| 28 | private ModelUtil() {} |
||
| 29 | |||
| 30 | public static void log(String tag, String msg) |
||
| 31 | { |
||
| 32 | if (verbose) |
||
| 33 | Gdx.app.log(tag, msg); |
||
| 34 | } |
||
| 35 | |||
| 36 | public static Model createModelFromFile(Graphics graphics, FileHandle fileHandle) throws IOException |
||
| 37 | { |
||
| 38 | File file = new File(fileHandle.read()); |
||
| 39 | Model model = loadModel(graphics, file); |
||
| 40 | file.close(); |
||
| 41 | return model; |
||
| 42 | } |
||
| 43 | |||
| 44 | |||
| 45 | public static Model loadModel(Graphics graphics, File modelFile) throws IOException |
||
| 46 | { |
||
| 47 | log(LOG_TAG, "Loading file"); |
||
| 48 | |||
| 49 | byte byteOrdering = modelFile.readByte(); |
||
| 50 | log(LOG_TAG, "Byte Ordering: " + (byteOrdering == 0 ? "Little Endian" : "Big Endian")); |
||
| 51 | |||
| 52 | if (byteOrdering == 0) |
||
| 53 | modelFile.setEndianness(File.Endianness.LITTLE_ENDIAN); |
||
| 54 | else |
||
| 55 | modelFile.setEndianness(File.Endianness.BIG_ENDIAN); |
||
| 56 | |||
| 57 | String header = modelFile.readString(8); |
||
| 58 | log(LOG_TAG, "Header: " + header); |
||
| 59 | |||
| 60 | if (header.compareTo("SUXMODEL") != 0) |
||
| 61 | throw new IOException("Header incorrect, must be 'SUXMODEL': " + header); |
||
| 62 | |||
| 63 | int version = modelFile.readInt(); |
||
| 64 | log(LOG_TAG, "Version: " + version); |
||
| 65 | if (version != 0) |
||
| 66 | throw new IOException("Version incorrect, must be 0: " + version); |
||
| 67 | |||
| 68 | String name = modelFile.readString(); |
||
| 69 | log(LOG_TAG, "Name: " + name); |
||
| 70 | |||
| 71 | int meshCount = modelFile.readInt(); |
||
| 72 | log(LOG_TAG, "Mesh Count: " + meshCount); |
||
| 73 | |||
| 74 | Model model = new Model(name); |
||
| 75 | |||
| 76 | Mesh[] meshes = new Mesh[meshCount]; |
||
| 77 | |||
| 78 | for (int i = 0; i < meshCount; i++) |
||
| 79 | { |
||
| 80 | String meshName = modelFile.readString(); |
||
| 81 | log(LOG_TAG, "[" + i + "] Mesh Name: " + meshName); |
||
| 82 | |||
| 83 | meshes[i] = new Mesh(graphics, meshName); |
||
| 84 | |||
| 85 | BoundingBox box = new BoundingBox(); |
||
| 86 | |||
| 87 | box.min = modelFile.readVector3(); |
||
| 88 | log(LOG_TAG, "[" + i + "] BB Min: " + box.min.x + ", " + box.min.y + ", " + box.min.z); |
||
| 89 | |||
| 90 | box.max = modelFile.readVector3(); |
||
| 91 | log(LOG_TAG, "[" + i + "] BB Max: " + box.max.x + ", " + box.max.y + ", " + box.max.z); |
||
| 92 | |||
| 93 | meshes[i].setBoundingBox(box); |
||
| 94 | |||
| 95 | boolean dynamic = modelFile.readBool(); |
||
| 96 | log(LOG_TAG, "[" + i + "] Dynamic: " + (dynamic ? "yes" : "no")); |
||
| 97 | |||
| 98 | boolean deleteSource = modelFile.readBool(); |
||
| 99 | log(LOG_TAG, "[" + i + "] DeleteSource: " + (deleteSource ? "yes" : "no")); |
||
| 100 | |||
| 101 | // geometry |
||
| 102 | Geometry geometry = loadGeometry(graphics, modelFile); |
||
| 103 | |||
| 104 | meshes[i].setGeometry(geometry); |
||
| 105 | |||
| 106 | // bones - currently ignored |
||
| 107 | int boneCount = modelFile.readInt(); |
||
| 108 | for (int bone = 0; bone < boneCount; bone++) |
||
| 109 | { |
||
| 110 | String boneName = modelFile.readString(); |
||
| 111 | Matrix4 boneTransform = modelFile.readMatrix4(); |
||
| 112 | Matrix4 boneTransformInverse = modelFile.readMatrix4(); |
||
| 113 | Vector3 bonePosition = modelFile.readVector3(); |
||
| 114 | // TODO: Quaternion |
||
| 115 | Vector4 boneOrientation = modelFile.readVector4(); |
||
| 116 | Vector3 boneScale = modelFile.readVector3(); |
||
| 117 | } |
||
| 118 | for (int bone = 0; bone < boneCount; bone++) |
||
| 119 | { |
||
| 120 | int parentBoneIndex = modelFile.readInt(); |
||
| 121 | } |
||
| 122 | |||
| 123 | // groups |
||
| 124 | int groupCount = modelFile.readInt(); |
||
| 125 | log(LOG_TAG, "Group Count: " + groupCount); |
||
| 126 | |||
| 127 | MeshGroup[] groups = new MeshGroup[groupCount]; |
||
| 128 | |||
| 129 | for (int group = 0; group < groupCount; group++) |
||
| 130 | { |
||
| 131 | groups[group] = loadMeshGroup(meshes[i], modelFile); |
||
| 132 | } |
||
| 133 | |||
| 134 | meshes[i].setGroups(groups); |
||
| 135 | |||
| 136 | break; |
||
| 137 | } |
||
| 138 | |||
| 139 | model.setMeshes(meshes); |
||
| 140 | |||
| 141 | log(LOG_TAG, "Loading finished"); |
||
| 142 | |||
| 143 | return model; |
||
| 144 | } |
||
| 145 | |||
| 146 | public static Geometry loadGeometry(Graphics graphics, File modelFile) throws IOException |
||
| 147 | { |
||
| 148 | log(LOG_TAG, "=== Geometry Begin ==="); |
||
| 149 | |||
| 150 | int version = modelFile.readInt(); |
||
| 151 | log(LOG_TAG, "Geometry Version: " + version); |
||
| 152 | if (version != 2) |
||
| 153 | throw new IOException("Geometry Version incorrect, must be 2: " + version); |
||
| 154 | |||
| 155 | int primitiveType = modelFile.readInt(); |
||
| 156 | switch (primitiveType) |
||
| 157 | { |
||
| 158 | case 0: |
||
| 159 | log(LOG_TAG, "PrimitiveType: Triangles"); |
||
| 160 | break; |
||
| 161 | case 1: |
||
| 162 | log(LOG_TAG, "PrimitiveType: Triangle Strip"); |
||
| 163 | break; |
||
| 164 | case 2: |
||
| 165 | log(LOG_TAG, "PrimitiveType: Lines"); |
||
| 166 | break; |
||
| 167 | case 3: |
||
| 168 | log(LOG_TAG, "PrimitiveType: Line Strip"); |
||
| 169 | break; |
||
| 170 | case 4: |
||
| 171 | log(LOG_TAG, "PrimitiveType: Points"); |
||
| 172 | break; |
||
| 173 | } |
||
| 174 | |||
| 175 | int vertexCount = modelFile.readInt(); |
||
| 176 | log(LOG_TAG, "Vertex Count: " + vertexCount); |
||
| 177 | |||
| 178 | int indexCount = modelFile.readInt(); |
||
| 179 | log(LOG_TAG, "Index Count: " + indexCount); |
||
| 180 | |||
| 181 | int streamCount = modelFile.readInt(); |
||
| 182 | log(LOG_TAG, "Stream Count: " + streamCount); |
||
| 183 | |||
| 184 | VertexStream[] streams = new VertexStream[streamCount]; |
||
| 185 | |||
| 186 | for (int i = 0; i < streamCount; i++) |
||
| 187 | { |
||
| 188 | log(LOG_TAG, "=== BEGIN VertexStream [" + i + "] ==="); |
||
| 189 | streams[i] = loadVertexStream(graphics, modelFile); |
||
| 190 | log(LOG_TAG, "=== END VertexStream [" + i + "] ==="); |
||
| 191 | } |
||
| 192 | |||
| 193 | boolean hasIndexStream = modelFile.readBool(); |
||
| 194 | log(LOG_TAG, "Has Index Stream" + (hasIndexStream ? "Yes" : "No")); |
||
| 195 | |||
| 196 | IndexStream indexStream = null; |
||
| 197 | if (hasIndexStream) |
||
| 198 | { |
||
| 199 | log(LOG_TAG, "=== BEGIN IndexStream ==="); |
||
| 200 | indexStream = loadIndexStream(graphics, modelFile); |
||
| 201 | log(LOG_TAG, "=== END IndexStream ==="); |
||
| 202 | } |
||
| 203 | |||
| 204 | Geometry geometry = new Geometry(graphics, Geometry.PrimitiveType.values()[primitiveType], vertexCount, indexCount); |
||
| 205 | geometry.setVertexStreams(streams); |
||
| 206 | geometry.setIndexStream(indexStream); |
||
| 207 | |||
| 208 | log(LOG_TAG, "=== Geometry End ==="); |
||
| 209 | |||
| 210 | return geometry; |
||
| 211 | } |
||
| 212 | |||
| 213 | public static VertexStream loadVertexStream(Graphics graphics, File modelFile) throws IOException |
||
| 214 | { |
||
| 215 | VertexStream.StreamType streamType = (modelFile.readInt() == 1) ? VertexStream.StreamType.INDIVIDUAL : VertexStream.StreamType.INTERLEAVED; |
||
| 216 | log(LOG_TAG, "Stream Type: " + streamType.toString()); |
||
| 217 | |||
| 218 | String streamName = modelFile.readString(); |
||
| 219 | log(LOG_TAG, "Stream Name: " + streamName); |
||
| 220 | |||
| 221 | int streamVertexCount = modelFile.readInt(); |
||
| 222 | log(LOG_TAG, "Stream Vertex Count: " + streamVertexCount); |
||
| 223 | |||
| 224 | int coordsPerElement = modelFile.readInt(); |
||
| 225 | log(LOG_TAG, "Coords per Element: " + coordsPerElement); |
||
| 226 | |||
| 227 | int bytesPerElement = modelFile.readInt(); |
||
| 228 | log(LOG_TAG, "Bytes per Element: " + bytesPerElement); |
||
| 229 | |||
| 230 | // Stream Begin |
||
| 231 | byte[] streamBuffer = loadStream(modelFile); |
||
| 232 | // Stream End |
||
| 233 | |||
| 234 | VertexAttribute[] attribs = null; |
||
| 235 | |||
| 236 | if (streamType == VertexStream.StreamType.INDIVIDUAL) |
||
| 237 | { |
||
| 238 | attribs = new VertexAttribute[1]; |
||
| 239 | attribs[0] = loadAttribute(modelFile); |
||
| 240 | } |
||
| 241 | else if (streamType == VertexStream.StreamType.INTERLEAVED) |
||
| 242 | { |
||
| 243 | int vertexAttribCount = modelFile.readInt(); |
||
| 244 | log(LOG_TAG, "Vertex Attrib Count: " + vertexAttribCount); |
||
| 245 | |||
| 246 | attribs = new VertexAttribute[vertexAttribCount]; |
||
| 247 | |||
| 248 | for (int attrib = 0; attrib < vertexAttribCount; attrib++) |
||
| 249 | { |
||
| 250 | log(LOG_TAG, "=== BEGIN VertexAttribute [" + attrib + "] ==="); |
||
| 251 | // Vertex Attribute |
||
| 252 | attribs[attrib] = loadAttribute(modelFile); |
||
| 253 | log(LOG_TAG, "=== END VertexAttribute [" + attrib + "] ==="); |
||
| 254 | } |
||
| 255 | } |
||
| 256 | else |
||
| 257 | { |
||
| 258 | throw new IOException(); |
||
| 259 | } |
||
| 260 | |||
| 261 | VertexStream stream = new VertexStream(graphics, streamType, streamName, attribs, false); |
||
| 262 | stream.setData(streamBuffer, coordsPerElement, bytesPerElement); |
||
| 263 | |||
| 264 | return stream; |
||
| 265 | } |
||
| 266 | |||
| 267 | public static VertexAttribute loadAttribute(File modelFile) throws IOException |
||
| 268 | { |
||
| 269 | int suxType = modelFile.readInt(); |
||
| 270 | log(LOG_TAG, "Attrib Data Type: " + suxType); |
||
| 271 | |||
| 272 | if (!VertexAttribute.isValidType(suxType)) |
||
| 273 | throw new IOException("Invalid vertex attribute type: " + suxType); |
||
| 274 | |||
| 275 | int dataFormat = modelFile.readInt(); |
||
| 276 | log(LOG_TAG, "Attrib Data Format: " + dataFormat); |
||
| 277 | |||
| 278 | if (dataFormat != 0) |
||
| 279 | throw new IOException("Unsupported Data Format (must be 0 / Float): " + dataFormat); |
||
| 280 | |||
| 281 | int coordsPerElement = modelFile.readInt(); |
||
| 282 | log(LOG_TAG, "Attrib Coords Per Element: " + coordsPerElement); |
||
| 283 | |||
| 284 | int byteOffset = modelFile.readInt(); |
||
| 285 | log(LOG_TAG, "Attrib Byte Offset: " + byteOffset); |
||
| 286 | |||
| 287 | VertexAttribute attrib = new VertexAttribute(VertexAttribute.toInternalType(suxType), coordsPerElement, byteOffset); |
||
| 288 | |||
| 289 | return attrib; |
||
| 290 | } |
||
| 291 | |||
| 292 | public static IndexStream loadIndexStream(Graphics graphics, File modelFile) throws IOException |
||
| 293 | { |
||
| 294 | int indexCount = modelFile.readInt(); |
||
| 295 | log(LOG_TAG, "Index Count: " + indexCount); |
||
| 296 | |||
| 297 | int dataFormat = modelFile.readInt(); |
||
| 298 | log(LOG_TAG, "Data Format: " + dataFormat); |
||
| 299 | if (dataFormat != 1) |
||
| 300 | throw new IOException("Data Format unsupported, must be 1 (Int16): " + dataFormat); |
||
| 301 | |||
| 302 | // Stream Begin |
||
| 303 | byte[] streamBuffer = loadStream(modelFile); |
||
| 304 | // Stream End |
||
| 305 | |||
| 306 | IndexStream indexStream = new IndexStream(graphics); |
||
| 307 | indexStream.setData(streamBuffer); |
||
| 308 | |||
| 309 | return indexStream; |
||
| 310 | } |
||
| 311 | |||
| 312 | public static byte[] loadStream(File modelFile) throws IOException |
||
| 313 | { |
||
| 314 | // Store endianness because the stream might change it |
||
| 315 | File.Endianness endianness = modelFile.getEndianness(); |
||
| 316 | |||
| 317 | byte byteOrdering = modelFile.readByte(); |
||
| 318 | log(LOG_TAG, "Stream Byte Ordering: " + (byteOrdering == 0 ? "Little Endian" : "Big Endian")); |
||
| 319 | |||
| 320 | if (byteOrdering == 0) |
||
| 321 | modelFile.setEndianness(File.Endianness.LITTLE_ENDIAN); |
||
| 322 | else |
||
| 323 | modelFile.setEndianness(File.Endianness.BIG_ENDIAN); |
||
| 324 | |||
| 325 | byte charFormat = modelFile.readByte(); |
||
| 326 | log(LOG_TAG, "Stream CharFormat: " + (charFormat == 0 ? "ASCII" : "UTF16")); |
||
| 327 | |||
| 328 | int byteLength = modelFile.readInt(); |
||
| 329 | log(LOG_TAG, "Stream Byte Length: " + byteLength); |
||
| 330 | |||
| 331 | byte[] buffer = new byte[byteLength]; |
||
| 332 | modelFile.readFully(buffer, 0, byteLength); |
||
| 333 | |||
| 334 | // Restore endianness |
||
| 335 | modelFile.setEndianness(endianness); |
||
| 336 | |||
| 337 | return buffer; |
||
| 338 | } |
||
| 339 | |||
| 340 | public static MeshGroup loadMeshGroup(Mesh mesh, File modelFile) throws IOException |
||
| 341 | { |
||
| 342 | log(LOG_TAG, "=== Mesh.Group Begin ==="); |
||
| 343 | |||
| 344 | String name = modelFile.readString(); |
||
| 345 | log(LOG_TAG, "Name: " + name); |
||
| 346 | |||
| 347 | String effectFile = modelFile.readString(); |
||
| 348 | log(LOG_TAG, "-- Effect file: " + effectFile); |
||
| 349 | |||
| 350 | MeshGroup group = new MeshGroup(mesh, name); |
||
| 351 | |||
| 352 | // TODO: do actual parsing of external technique |
||
| 353 | Effect effect = new Effect(mesh.getGraphics(), effectFile); |
||
| 354 | |||
| 355 | ShaderProgram shader = ShaderUtil.createShaderFromFile(mesh.getGraphics(), Gdx.files.internal("data/shaders/default.vs"), Gdx.files.internal("data/shaders/default.fs")); |
||
| 356 | Technique[] effectTechs = new Technique[1]; |
||
| 357 | effectTechs[0] = new Technique(effect, "diffuse", shader); |
||
| 358 | |||
| 359 | effect.setTechniques(effectTechs); |
||
| 360 | |||
| 361 | int techniqueCount = modelFile.readInt(); |
||
| 362 | log(LOG_TAG, "-- Technique Count: " + techniqueCount); |
||
| 363 | |||
| 364 | MeshGroup.TechniqueRef[] techRefs = new MeshGroup.TechniqueRef[techniqueCount]; |
||
| 365 | |||
| 366 | for (int i = 0; i < techniqueCount; i++) |
||
| 367 | { |
||
| 368 | String staticTechniqueName = modelFile.readString(); |
||
| 369 | log(LOG_TAG, "-- Static Technique: " + staticTechniqueName); |
||
| 370 | String skinnedTechniqueName = modelFile.readString(); |
||
| 371 | log(LOG_TAG, "-- Skinned Technique: " + skinnedTechniqueName); |
||
| 372 | |||
| 373 | // TODO: read technique from parsed effect file |
||
| 374 | techRefs[i] = group.new TechniqueRef(effectTechs[0], effectTechs[0]); |
||
| 375 | } |
||
| 376 | |||
| 377 | group.setTechniqueRefs(techRefs); |
||
| 378 | |||
| 379 | String bonesParameterName = modelFile.readString(); |
||
| 380 | |||
| 381 | int firstIndex = modelFile.readInt(); |
||
| 382 | log(LOG_TAG, "First Index: " + firstIndex); |
||
| 383 | int lastIndex = modelFile.readInt(); |
||
| 384 | log(LOG_TAG, "Last Index: " + lastIndex); |
||
| 385 | |||
| 386 | int firstVertex = modelFile.readInt(); |
||
| 387 | log(LOG_TAG, "First Vertex: " + firstVertex); |
||
| 388 | int lastVertex = modelFile.readInt(); |
||
| 389 | log(LOG_TAG, "Last Vertex: " + lastVertex); |
||
| 390 | |||
| 391 | group.setIndices(firstIndex, lastIndex, firstVertex, lastVertex); |
||
| 392 | |||
| 393 | // TODO: make render state class |
||
| 394 | RenderStatesConfiguration rs = loadRenderState(mesh.getGraphics(), modelFile); |
||
| 395 | |||
| 396 | group.setRenderStates(rs); |
||
| 397 | |||
| 398 | int variablesCount = modelFile.readInt(); |
||
| 399 | log(LOG_TAG, "== Variable Count: " + variablesCount); |
||
| 400 | |||
| 401 | Effect.Variable[] vars = new Effect.Variable[variablesCount]; |
||
| 402 | |||
| 403 | for (int i = 0; i < variablesCount; i++) |
||
| 404 | { |
||
| 405 | String variableName = modelFile.readString(); |
||
| 406 | |||
| 407 | log(LOG_TAG, "-- [" + i + "] Variable Name: " + variableName); |
||
| 408 | |||
| 409 | int variableType = modelFile.readInt(); |
||
| 410 | |||
| 411 | switch (variableType) |
||
| 412 | { |
||
| 413 | case Effect.Variable.TYPE_TEXTURE2D: // Texture2D |
||
| 414 | case Effect.Variable.TYPE_TEXTURE3D: // Texture3D |
||
| 415 | case Effect.Variable.TYPE_TEXTURECUBE: // TextureCube |
||
| 416 | { |
||
| 417 | String texFile = modelFile.readString(); |
||
| 418 | log(LOG_TAG, "-- [" + i + "] Variable Type: Texture (" + texFile + ")"); |
||
| 419 | |||
| 420 | Texture texture = new Texture(Gdx.files.internal("data/" + texFile)); |
||
| 421 | vars[i] = effect.new VariableTexture(variableName, texture); |
||
| 422 | |||
| 423 | break; |
||
| 424 | } |
||
| 425 | case Effect.Variable.TYPE_BOOL: // Bool |
||
| 426 | { |
||
| 427 | boolean b = modelFile.readBool(); |
||
| 428 | log(LOG_TAG, "-- [" + i + "] Variable Type: bool (" + (b ? "true" : "false") + ")"); |
||
| 429 | |||
| 430 | vars[i] = effect.new VariableBool(variableName, b); |
||
| 431 | |||
| 432 | break; |
||
| 433 | } |
||
| 434 | case Effect.Variable.TYPE_INT: // Int |
||
| 435 | { |
||
| 436 | int n = modelFile.readInt(); |
||
| 437 | log(LOG_TAG, "-- [" + i + "] Variable Type: int (" + n + ")"); |
||
| 438 | |||
| 439 | vars[i] = effect.new VariableInt(variableName, n); |
||
| 440 | |||
| 441 | break; |
||
| 442 | } |
||
| 443 | case Effect.Variable.TYPE_FLOAT: // Float |
||
| 444 | { |
||
| 445 | float f = modelFile.readFloat(); |
||
| 446 | log(LOG_TAG, "-- [" + i + "] Variable Type: float (" + f + ")"); |
||
| 447 | |||
| 448 | vars[i] = effect.new VariableFloat(variableName, f); |
||
| 449 | |||
| 450 | break; |
||
| 451 | } |
||
| 452 | case Effect.Variable.TYPE_VECTOR2: // Vector2 |
||
| 453 | { |
||
| 454 | Vector2 v2 = modelFile.readVector2(); |
||
| 455 | log(LOG_TAG, "-- [" + i + "] Variable Type: Vector2 (" + v2.x + ", " + v2.y + ")"); |
||
| 456 | |||
| 457 | vars[i] = effect.new VariableVector2(variableName, v2); |
||
| 458 | |||
| 459 | break; |
||
| 460 | } |
||
| 461 | case Effect.Variable.TYPE_VECTOR3: // Vector3 |
||
| 462 | { |
||
| 463 | Vector3 v3 = modelFile.readVector3(); |
||
| 464 | log(LOG_TAG, "-- [" + i + "] Variable Type: Vector3 (" + v3.x + ", " + v3.y + ", " + v3.z + ")"); |
||
| 465 | |||
| 466 | vars[i] = effect.new VariableVector3(variableName, v3); |
||
| 467 | |||
| 468 | break; |
||
| 469 | } |
||
| 470 | case Effect.Variable.TYPE_VECTOR4: // Vector4 |
||
| 471 | { |
||
| 472 | Vector4 v4 = modelFile.readVector4(); |
||
| 473 | log(LOG_TAG, "-- [" + i + "] Variable Type: Vector3 (" + v4.x + ", " + v4.y + ", " + v4.z + ", " + v4.w + ")"); |
||
| 474 | |||
| 475 | vars[i] = effect.new VariableVector4(variableName, v4); |
||
| 476 | |||
| 477 | break; |
||
| 478 | } |
||
| 479 | } |
||
| 480 | } |
||
| 481 | |||
| 482 | effect.setVariables(vars); |
||
| 483 | effect.connectVariables(); |
||
| 484 | group.setEffect(effect); |
||
| 485 | |||
| 486 | // Bone Reindexing for tighter usage of uniforms |
||
| 487 | int boneIndexCount = modelFile.readInt(); |
||
| 488 | for (int i = 0; i < boneIndexCount; i++) |
||
| 489 | { |
||
| 490 | int originalIndex = modelFile.readInt(); |
||
| 491 | int newIndex = modelFile.readInt(); |
||
| 492 | } |
||
| 493 | |||
| 494 | log(LOG_TAG, "=== Mesh.Group End==="); |
||
| 495 | return group; |
||
| 496 | } |
||
| 497 | |||
| 498 | @SuppressWarnings("unused") |
||
| 499 | public static RenderStatesConfiguration loadRenderState(Graphics graphics, File modelFile) throws IOException |
||
| 500 | { |
||
| 501 | RenderStatesConfiguration rs = new RenderStatesConfiguration(graphics); |
||
| 502 | |||
| 503 | // Alpha test not supported |
||
| 504 | boolean alphaTestEnabled = modelFile.readBool(); |
||
| 505 | float alphaTestThreshold = modelFile.readFloat(); |
||
| 506 | int alphaTestComparisonFunc = modelFile.readInt(); |
||
| 507 | |||
| 508 | boolean blendingEnabled = modelFile.readBool(); |
||
| 509 | int blendingMode = modelFile.readInt(); |
||
| 510 | |||
| 511 | rs.setBlendingEnabled(blendingEnabled); |
||
| 512 | rs.setBlendingMode(blendingMode); |
||
| 513 | |||
| 514 | boolean cullingEnabled = modelFile.readBool(); |
||
| 515 | int cullingWinding = modelFile.readInt(); |
||
| 516 | |||
| 517 | rs.setCullingEnabled(cullingEnabled); |
||
| 518 | rs.setCullingWinding(cullingWinding); |
||
| 519 | |||
| 520 | boolean depthTestEnabled = modelFile.readBool(); |
||
| 521 | boolean depthBufferWriteEnabled = modelFile.readBool(); |
||
| 522 | int depthTestComparisonFunc = modelFile.readInt(); |
||
| 523 | |||
| 524 | rs.setDepthTestEnabled(depthTestEnabled); |
||
| 525 | rs.setDepthBufferWriteEnabled(depthBufferWriteEnabled); |
||
| 526 | rs.setDepthTestComparisonFunc(depthTestComparisonFunc); |
||
| 527 | |||
| 528 | // Polygon Mode not supported |
||
| 529 | int polygonMode = modelFile.readInt(); |
||
| 530 | |||
| 531 | return rs; |
||
| 532 | } |
||
| 533 | } |
||
| 534 | |||
| 535 | |||
| 536 |