fix up ModelTileMesh so it is easier to use with loaded Models. add bounding volume field to TileMesh

This commit is contained in:
Gered 2013-07-16 15:37:58 -04:00
parent 4a881184fb
commit 882264ba44
4 changed files with 108 additions and 26 deletions

View file

@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.blarg.gdx.Bitfield;
import com.blarg.gdx.graphics.TextureAtlas;
import com.blarg.gdx.graphics.Vertices;
@ -13,6 +14,7 @@ public class CubeTileMesh extends TileMesh {
static final Vector3 A = new Vector3(-0.5f, -0.5f, -0.5f);
static final Vector3 B = new Vector3(0.5f, 0.5f, 0.5f);
BoundingBox bounds;
Vertices vertices;
Vector3[] collisionVertices;
@ -28,6 +30,11 @@ public class CubeTileMesh extends TileMesh {
return Bitfield.isSet(side, faces);
}
@Override
public BoundingBox getBounds() {
return bounds;
}
@Override
public Vertices getVertices() {
return vertices;
@ -92,6 +99,7 @@ public class CubeTileMesh extends TileMesh {
setupFaceVertices(numVertices, topTexture, bottomTexture, frontTexture, backTexture, leftTexture, rightTexture);
setupCollisionVertices();
bounds = new BoundingBox(TileMesh.UNIT_BOUNDS);
}
private void setupFaceVertices(

View file

@ -11,21 +11,31 @@ 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.TextureAtlas;
import com.blarg.gdx.graphics.Vertices;
import com.blarg.gdx.math.MathHelpers;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.Map;
public class ModelTileMesh extends TileMesh {
final Vector3 tmpPosition = new Vector3();
final Vector3 tmpNormal = new Vector3();
static final Vector3 tmpPosition = new Vector3();
static final Vector3 tmpNormal = new Vector3();
static final BoundingBox tmpModelBounds = new BoundingBox();
static final Vector3 tmpScaleFactor = new Vector3();
BoundingBox bounds;
Vertices vertices;
Array<Vector3> collisionVertices;
@Override
public BoundingBox getBounds() {
return bounds;
}
@Override
public Vertices getVertices() {
return vertices;
@ -36,19 +46,41 @@ public class ModelTileMesh extends TileMesh {
return collisionVertices.items;
}
public ModelTileMesh(Model model, Map<String, TextureRegion> textures, byte opaqueSides, byte lightValue, boolean alpha, float translucency, Color color) {
public ModelTileMesh(
Model model,
Map<String, TextureRegion> textures,
byte opaqueSides,
byte lightValue,
boolean alpha,
float translucency,
Color color,
Vector3 scaleToSize,
Vector3 positionOffset
) {
super(opaqueSides, alpha, translucency, lightValue, color);
setupMesh(model, textures);
setupCollisionVertices(model);
setupMesh(model, textures, scaleToSize, positionOffset);
setupCollisionVertices(model, scaleToSize, positionOffset);
}
public ModelTileMesh(Model model, Model collisionModel, Map<String, TextureRegion> textures, byte opaqueSides, byte lightValue, boolean alpha, float translucency, Color color) {
public ModelTileMesh(
Model model,
Model collisionModel,
Map<String, TextureRegion> textures,
byte opaqueSides,
byte lightValue,
boolean alpha,
float translucency,
Color color,
Vector3 scaleToSize,
Vector3 positionOffset,
Vector3 collisionPositionOffset
) {
super(opaqueSides, alpha, translucency, lightValue, color);
setupMesh(model, textures);
setupCollisionVertices(collisionModel);
setupMesh(model, textures, scaleToSize, positionOffset);
setupCollisionVertices(collisionModel, scaleToSize, collisionPositionOffset);
}
private void setupMesh(Model model, Map<String, TextureRegion> textures) {
private void setupMesh(Model model, Map<String, TextureRegion> textures, Vector3 scaleToSize, Vector3 positionOffset) {
int numVertices = countModelVertices(model);
vertices = new Vertices(
numVertices,
@ -58,11 +90,15 @@ public class ModelTileMesh extends TileMesh {
VertexAttribute.TexCoords(0)
);
model.getBoundingBox(tmpModelBounds);
MathHelpers.getScaleFactor(tmpModelBounds.getDimensions(), scaleToSize, tmpScaleFactor);
bounds = new BoundingBox().set(Vector3.Zero, scaleToSize);
for (int i = 0; i < model.nodes.size; ++i)
addModelNodeVertices(model.nodes.get(i), textures);
addModelNodeVertices(model.nodes.get(i), textures, tmpScaleFactor, positionOffset);
}
private void addModelNodeVertices(Node node, Map<String, TextureRegion> textures) {
private void addModelNodeVertices(Node node, Map<String, TextureRegion> textures, Vector3 scaleFactor, Vector3 positionOffset) {
final Matrix4 transform = node.globalTransform; // TODO: test that this is the right transform to use?
for (int i = 0; i < node.parts.size; ++i) {
@ -77,8 +113,10 @@ public class ModelTileMesh extends TileMesh {
int index = indices.get(meshPart.indexOffset + j);
int offset = index * strideInFloats;
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2));
tmpPosition.mul(transform);
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
.add(positionOffset)
.scl(scaleFactor)
.mul(transform);
this.vertices.setPos(tmpPosition);
offset += 3;
@ -90,8 +128,8 @@ public class ModelTileMesh extends TileMesh {
// 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));
tmpNormal.mul(transform);
tmpNormal.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
.mul(transform);
this.vertices.setNor(tmpNormal);
offset += 3;
} else
@ -112,17 +150,20 @@ public class ModelTileMesh extends TileMesh {
}
for (int i = 0; i < node.children.size; ++i)
addModelNodeVertices(node.children.get(i), textures);
addModelNodeVertices(node.children.get(i), textures, tmpScaleFactor, positionOffset);
}
private void setupCollisionVertices(Model collisionModel) {
private void setupCollisionVertices(Model collisionModel, Vector3 scaleToSize, Vector3 positionOffset) {
collisionModel.getBoundingBox(tmpModelBounds);
MathHelpers.getScaleFactor(tmpModelBounds.getDimensions(), scaleToSize, tmpScaleFactor);
int numVertices = countModelVertices(collisionModel);
collisionVertices = new Array<Vector3>(true, numVertices, Vector3.class);
for (int i = 0; i < collisionModel.nodes.size; ++i)
addModelNodeCollisionVertices(collisionModel.nodes.get(i));
addModelNodeCollisionVertices(collisionModel.nodes.get(i), tmpScaleFactor, positionOffset);
}
private void addModelNodeCollisionVertices(Node node) {
private void addModelNodeCollisionVertices(Node node, Vector3 scaleFactor, Vector3 positionOffset) {
final Matrix4 transform = node.globalTransform; // TODO: test that this is the right transform to use?
for (int i = 0; i < node.parts.size; ++i) {
@ -136,14 +177,16 @@ public class ModelTileMesh extends TileMesh {
int index = indices.get(meshPart.indexOffset + j);
int offset = index * strideInFloats;
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2));
tmpPosition.mul(transform);
tmpPosition.set(vertices.get(offset), vertices.get(offset + 1), vertices.get(offset + 2))
.add(positionOffset)
.scl(scaleFactor)
.mul(transform);
collisionVertices.add(new Vector3(tmpPosition));
}
}
for (int i = 0; i < node.children.size; ++i)
addModelNodeCollisionVertices(node.children.get(i));
addModelNodeCollisionVertices(node.children.get(i), tmpScaleFactor, positionOffset);
}
private int countModelVertices(Model model) {

View file

@ -2,12 +2,15 @@ package com.blarg.gdx.tilemap3d;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.utils.Disposable;
import com.blarg.gdx.Bitfield;
import com.blarg.gdx.graphics.Vertices;
public abstract class TileMesh implements Disposable {
public static final Vector3 OFFSET = new Vector3(0.5f, 0.5f, 0.5f);
public static final Vector3 UNIT_SIZE = new Vector3(1.0f, 1.0f, 1.0f);
public static final BoundingBox UNIT_BOUNDS = new BoundingBox(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, 0.5f));
public static final byte SIDE_TOP = 1;
public static final byte SIDE_BOTTOM = 2;
@ -25,6 +28,7 @@ public abstract class TileMesh implements Disposable {
public final byte lightValue;
public final Color color;
public abstract BoundingBox getBounds();
public abstract Vertices getVertices();
public abstract Vector3[] getCollisionVertices();

View file

@ -3,6 +3,7 @@ package com.blarg.gdx.tilemap3d;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.blarg.gdx.Bitfield;
import com.blarg.gdx.graphics.TextureAtlas;
@ -30,13 +31,39 @@ public class TileMeshCollection {
return meshes.size - 1;
}
public int add(Model model, Map<String, TextureRegion> textures, byte opaqueSides, byte lightValue, boolean alpha, float translucency, Color color) {
ModelTileMesh tileMesh = new ModelTileMesh(model, textures, opaqueSides, lightValue, alpha, translucency, color);
public int add(
Model model,
Map<String, TextureRegion> textures,
byte opaqueSides,
byte lightValue,
boolean alpha,
float translucency,
Color color,
Vector3 scaleToSize,
Vector3 positionOffset
) {
ModelTileMesh tileMesh = new ModelTileMesh(
model, textures, opaqueSides, lightValue, alpha, translucency, color, scaleToSize, positionOffset
);
return addMesh(tileMesh);
}
public int add(Model model, Model collisionModel, Map<String, TextureRegion> textures, byte opaqueSides, byte lightValue, boolean alpha, float translucency, Color color) {
ModelTileMesh tileMesh = new ModelTileMesh(model, collisionModel, textures, opaqueSides, lightValue, alpha, translucency, color);
public int add(
Model model,
Model collisionModel,
Map<String, TextureRegion> textures,
byte opaqueSides,
byte lightValue,
boolean alpha,
float translucency,
Color color,
Vector3 scaleToSize,
Vector3 positionOffset,
Vector3 collisionPositionOffset
) {
ModelTileMesh tileMesh = new ModelTileMesh(
model, collisionModel, textures, opaqueSides, lightValue, alpha, translucency, color, scaleToSize, positionOffset, collisionPositionOffset
);
return addMesh(tileMesh);
}