add abstract base class to be used for TileMesh's that work with Model objects
This commit is contained in:
parent
d3bacd32a9
commit
37c744d82f
127
src/com/blarg/gdx/tilemap3d/tilemesh/BaseModelTileMesh.java
Normal file
127
src/com/blarg/gdx/tilemap3d/tilemesh/BaseModelTileMesh.java
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package com.blarg.gdx.tilemap3d.tilemesh;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.VertexAttributes;
|
||||||
|
import com.badlogic.gdx.graphics.g3d.Model;
|
||||||
|
import com.badlogic.gdx.graphics.g3d.model.MeshPart;
|
||||||
|
import com.badlogic.gdx.graphics.g3d.model.Node;
|
||||||
|
import com.badlogic.gdx.graphics.g3d.model.NodePart;
|
||||||
|
import com.badlogic.gdx.math.Matrix4;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
|
import com.badlogic.gdx.math.collision.BoundingBox;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.blarg.gdx.graphics.Vertices;
|
||||||
|
import com.blarg.gdx.graphics.atlas.TextureAtlas;
|
||||||
|
import com.blarg.gdx.math.MathHelpers;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
public abstract class BaseModelTileMesh extends TileMesh {
|
||||||
|
private final Vector3 tmpPosition = new Vector3();
|
||||||
|
private final Vector3 tmpNormal = new Vector3();
|
||||||
|
private final BoundingBox tmpBounds = new BoundingBox();
|
||||||
|
|
||||||
|
public BaseModelTileMesh(byte opaqueSides, boolean alpha, float translucency, byte lightValue, Color color) {
|
||||||
|
super(opaqueSides, alpha, translucency, lightValue, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void collectModelNodeVertices(Node node, Vertices destVertices, MaterialTileMapping textures, Color color, Vector3 scaleFactor, Vector3 positionOffset) {
|
||||||
|
final Matrix4 transform = node.globalTransform;
|
||||||
|
|
||||||
|
for (int i = 0; i < node.parts.size; ++i) {
|
||||||
|
NodePart nodePart = node.parts.get(i);
|
||||||
|
MaterialTileMapping.TileTexture texture = textures.get(nodePart.material.id);
|
||||||
|
MeshPart meshPart = nodePart.meshPart;
|
||||||
|
ShortBuffer indices = meshPart.mesh.getIndicesBuffer();
|
||||||
|
FloatBuffer vertices = meshPart.mesh.getVerticesBuffer();
|
||||||
|
final int strideInFloats = meshPart.mesh.getVertexSize() / (Float.SIZE / 8);
|
||||||
|
|
||||||
|
if (destVertices.remainingSpace() < meshPart.numVertices)
|
||||||
|
throw new RuntimeException("Not enough space to collect this MeshPart's vertices.");
|
||||||
|
|
||||||
|
for (int j = 0; j < meshPart.numVertices; ++j) {
|
||||||
|
int index = indices.get(meshPart.indexOffset + j);
|
||||||
|
int offset = index * strideInFloats;
|
||||||
|
|
||||||
|
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
|
||||||
|
.add(positionOffset)
|
||||||
|
.scl(scaleFactor)
|
||||||
|
.mul(transform);
|
||||||
|
destVertices.setPos(tmpPosition);
|
||||||
|
offset += 3;
|
||||||
|
|
||||||
|
if (meshPart.mesh.getVertexAttribute(VertexAttributes.Usage.Color) != null) {
|
||||||
|
// TODO: blend mesh color and source model color somehow?
|
||||||
|
destVertices.setCol(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2), vertices.get(offset + 3));
|
||||||
|
offset += 4;
|
||||||
|
} else
|
||||||
|
destVertices.setCol(color);
|
||||||
|
|
||||||
|
// TODO: better to throw exception (or check beforehand) if this is missing? setting zero's doesn't feel like the best solution
|
||||||
|
if (meshPart.mesh.getVertexAttribute(VertexAttributes.Usage.Normal) != null) {
|
||||||
|
tmpNormal.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
|
||||||
|
.rot(transform);
|
||||||
|
destVertices.setNor(tmpNormal);
|
||||||
|
offset += 3;
|
||||||
|
} else
|
||||||
|
destVertices.setNor(Vector3.Zero);
|
||||||
|
|
||||||
|
// TODO: better to throw exception (or check beforehand) if this is missing? setting zero's doesn't feel like the best solution
|
||||||
|
if (meshPart.mesh.getVertexAttribute(VertexAttributes.Usage.TextureCoordinates) != null) {
|
||||||
|
destVertices.setUV(
|
||||||
|
TextureAtlas.scaleTexCoordU(vertices.get(offset), texture.materialMinU, texture.materialMaxU, texture.region),
|
||||||
|
TextureAtlas.scaleTexCoordV(vertices.get(offset + 1), texture.materialMinV, texture.materialMaxV, texture.region)
|
||||||
|
);
|
||||||
|
offset += 3;
|
||||||
|
} else
|
||||||
|
destVertices.setUV(Vector2.Zero);
|
||||||
|
|
||||||
|
destVertices.moveNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < node.children.size; ++i)
|
||||||
|
collectModelNodeVertices(node.children.get(i), destVertices, textures, color, scaleFactor, positionOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void collectModelNodeVertexPositions(Node node, Array<Vector3> destVertices, Vector3 scaleFactor, Vector3 positionOffset) {
|
||||||
|
final Matrix4 transform = node.globalTransform;
|
||||||
|
|
||||||
|
for (int i = 0; i < node.parts.size; ++i) {
|
||||||
|
NodePart nodePart = node.parts.get(i);
|
||||||
|
MeshPart meshPart = nodePart.meshPart;
|
||||||
|
ShortBuffer indices = meshPart.mesh.getIndicesBuffer();
|
||||||
|
FloatBuffer vertices = meshPart.mesh.getVerticesBuffer();
|
||||||
|
final int strideInFloats = meshPart.mesh.getVertexSize() / (Float.SIZE / 8);
|
||||||
|
|
||||||
|
for (int j = 0; j < meshPart.numVertices; ++j) {
|
||||||
|
int index = indices.get(meshPart.indexOffset + j);
|
||||||
|
int offset = index * strideInFloats;
|
||||||
|
|
||||||
|
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
|
||||||
|
.add(positionOffset)
|
||||||
|
.scl(scaleFactor)
|
||||||
|
.mul(transform);
|
||||||
|
destVertices.add(new Vector3(tmpPosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < node.children.size; ++i)
|
||||||
|
collectModelNodeVertexPositions(node.children.get(i), destVertices, scaleFactor, positionOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void getScaleFactorForModel(Model model, Vector3 scaleToSize, Vector3 out) {
|
||||||
|
model.getBoundingBox(tmpBounds);
|
||||||
|
MathHelpers.getScaleFactor(tmpBounds.getDimensions(), scaleToSize, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int countModelVertices(Model model) {
|
||||||
|
int numVertices = 0;
|
||||||
|
for (int i = 0; i < model.meshParts.size; ++i)
|
||||||
|
numVertices += model.meshParts.get(i).numVertices;
|
||||||
|
return numVertices;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue