use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class PartitionQuadTree method createPartition.
/**
* Creates a partition
* @param parent
* @param x
* @param z
* @param partition size
* @return partition tree node
*/
public PartitionTreeNode createPartition(PartitionTreeNode parent, int x, int y, int z, float partitionSize) {
PartitionTreeNode node;
node = new PartitionTreeNode();
node.partitionSize = partitionSize;
node.x = x;
node.y = y;
node.z = z;
node.parent = parent;
node.bv = new BoundingBox(new Vector3(x * partitionSize, y * partitionSize, z * partitionSize), new Vector3(x * partitionSize + partitionSize, y * partitionSize + partitionSize, z * partitionSize + partitionSize));
node.subNodes = null;
node.subNodesByCoordinate = null;
node.partitionRidigBodies = null;
// register in parent sub nodes
if (parent.subNodes == null) {
parent.subNodes = new ArrayList<PartitionTreeNode>();
}
parent.subNodes.add(node);
// register in parent sub nodes by coordinate
if (parent.subNodesByCoordinate == null) {
parent.subNodesByCoordinate = new HashMap<Key, PartitionTreeNode>();
}
Key key = new Key();
key.reset();
key.append(node.x);
key.append(",");
key.append(node.y);
key.append(",");
key.append(node.z);
parent.subNodesByCoordinate.put(key, node);
// create sub nodes
if (partitionSize > PARTITION_SIZE_MIN) {
for (int _y = 0; _y < 2; _y++) for (int _x = 0; _x < 2; _x++) for (int _z = 0; _z < 2; _z++) {
createPartition(node, (int) ((x * partitionSize) / (partitionSize / 2f)) + _x, (int) ((y * partitionSize) / (partitionSize / 2f)) + _y, (int) ((z * partitionSize) / (partitionSize / 2f)) + _z, partitionSize / 2f);
}
} else {
node.partitionRidigBodies = new ArrayList<RigidBody>();
}
//
return node;
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class ModelHelper method createNormalTangentsAndBitangents.
/**
* Create normal tangents and bitangents for groups with normal mapping
* @see http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/
* @param group
*/
public static void createNormalTangentsAndBitangents(Group group) {
// what we need
ArrayList<Vector3> tangentsArrayList = new ArrayList<Vector3>();
ArrayList<Vector3> bitangentsArrayList = new ArrayList<Vector3>();
// temporary variables
Vector2 uv0 = new Vector2();
Vector2 uv1 = new Vector2();
Vector2 uv2 = new Vector2();
Vector3 deltaPos1 = new Vector3();
Vector3 deltaPos2 = new Vector3();
Vector2 deltaUV1 = new Vector2();
Vector2 deltaUV2 = new Vector2();
Vector3 tmpVector3 = new Vector3();
// create it
Vector3[] vertices = group.getVertices();
Vector3[] normals = group.getNormals();
TextureCoordinate[] textureCoordinates = group.getTextureCoordinates();
for (FacesEntity faceEntity : group.getFacesEntities()) if (faceEntity.getMaterial() != null && faceEntity.getMaterial().hasNormalTexture() == true) {
for (Face face : faceEntity.getFaces()) {
// Shortcuts for vertices
int[] verticesIndexes = face.getVertexIndices();
Vector3 v0 = vertices[verticesIndexes[0]];
Vector3 v1 = vertices[verticesIndexes[1]];
Vector3 v2 = vertices[verticesIndexes[2]];
// shortcuts for UVs
int[] textureCoordinatesIndexes = face.getTextureCoordinateIndices();
uv0.set(textureCoordinates[textureCoordinatesIndexes[0]].getArray());
uv0.setY(1f - uv0.getY());
uv1.set(textureCoordinates[textureCoordinatesIndexes[1]].getArray());
uv1.setY(1f - uv1.getY());
uv2.set(textureCoordinates[textureCoordinatesIndexes[2]].getArray());
uv2.setY(1f - uv2.getY());
// edges of the triangle : position delta
deltaPos1.set(v1).sub(v0);
deltaPos2.set(v2).sub(v0);
// UV delta
deltaUV1.set(uv1).sub(uv0);
deltaUV2.set(uv2).sub(uv0);
// compute tangent and bitangent
float r = 1.0f / (deltaUV1.getX() * deltaUV2.getY() - deltaUV1.getY() * deltaUV2.getX());
Vector3 tangent = new Vector3(deltaPos1).scale(deltaUV2.getY()).sub(tmpVector3.set(deltaPos2).scale(deltaUV1.getY())).scale(r);
Vector3 bitangent = new Vector3(deltaPos2).scale(deltaUV1.getX()).sub(tmpVector3.set(deltaPos1).scale(deltaUV2.getX())).scale(r);
// set up tangent face indices
face.setTangentIndices(tangentsArrayList.size() + 0, tangentsArrayList.size() + 1, tangentsArrayList.size() + 2);
// set up bitangent face indices
face.setBitangentIndices(bitangentsArrayList.size() + 0, bitangentsArrayList.size() + 1, bitangentsArrayList.size() + 2);
// add to group tangents, bitangents
tangentsArrayList.add(tangent);
tangentsArrayList.add(tangent);
tangentsArrayList.add(tangent);
bitangentsArrayList.add(bitangent);
bitangentsArrayList.add(bitangent);
bitangentsArrayList.add(bitangent);
}
}
// set up tangents and bitangents if we have any
if (tangentsArrayList.size() > 0 && bitangentsArrayList.size() > 0) {
group.setTangents(tangentsArrayList);
group.setBitangents(bitangentsArrayList);
// going further
Vector3[] tangents = group.getTangents();
Vector3[] bitangents = group.getBitangents();
for (FacesEntity faceEntity : group.getFacesEntities()) if (faceEntity.getMaterial() != null && faceEntity.getMaterial().hasNormalTexture() == true) {
for (Face face : faceEntity.getFaces()) for (int i = 0; i < 3; i++) {
Vector3 normal = normals[face.getNormalIndices()[i]];
Vector3 tangent = tangents[face.getTangentIndices()[i]];
Vector3 bitangent = bitangents[face.getBitangentIndices()[i]];
tangent.sub(tmpVector3.set(normal).scale(Vector3.computeDotProduct(normal, tangent))).normalize();
if (Vector3.computeDotProduct(Vector3.computeCrossProduct(normal, tangent, tmpVector3), bitangent) < 0f) {
tangent.scale(-1f);
}
bitangent.normalize();
}
}
}
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class PartitionQuadTree method getObjectsNearTo.
/**
* Get objects near to
* @param cbv
* @return objects near to cbv
*/
public ArrayListIteratorMultiple<Entity> getObjectsNearTo(BoundingVolume cbv) {
Vector3 center = cbv.getCenter();
halfExtension.set(cbv.computeDimensionOnAxis(sideVector) + 0.2f, cbv.computeDimensionOnAxis(upVector) + 0.2f, cbv.computeDimensionOnAxis(forwardVector) + 0.2f).scale(0.5f);
boundingBox.getMin().set(center);
boundingBox.getMin().sub(halfExtension);
boundingBox.getMax().set(center);
boundingBox.getMax().add(halfExtension);
boundingBox.update();
entityIterator.clear();
int lookUps = 0;
for (int i = 0; i < treeRoot.subNodes.size(); i++) {
lookUps += doPartitionTreeLookUpNearEntities(treeRoot.subNodes.get(i), boundingBox, entityIterator);
}
return entityIterator;
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class PartitionQuadTree method addEntity.
/**
* Adds a object
* @param entity
*/
protected void addEntity(Entity entity) {
// update if already exists
ArrayList<PartitionTreeNode> objectPartitionsVector = objectPartitionNodes.get(entity.getId());
if (objectPartitionsVector != null) {
while (objectPartitionsVector.size() > 0) {
int lastIdx = objectPartitionsVector.size() - 1;
objectPartitionsVector.get(lastIdx).partitionObjects.remove(entity);
objectPartitionsVector.remove(lastIdx);
}
}
// determine max first level partition dimension
// convert to aabb for fast collision tests
BoundingVolume cbv = entity.getBoundingBoxTransformed();
Vector3 center = cbv.getCenter();
halfExtension.set(cbv.computeDimensionOnAxis(sideVector) + 0.2f, cbv.computeDimensionOnAxis(upVector) + 0.2f, cbv.computeDimensionOnAxis(forwardVector) + 0.2f).scale(0.5f);
boundingBox.getMin().set(center);
boundingBox.getMin().sub(halfExtension);
boundingBox.getMax().set(center);
boundingBox.getMax().add(halfExtension);
boundingBox.update();
// find, create root nodes if not exists
int minXPartition = (int) Math.floor(boundingBox.getMin().getX() / PARTITION_SIZE_MAX);
int minYPartition = (int) Math.floor(boundingBox.getMin().getY() / PARTITION_SIZE_MAX);
int minZPartition = (int) Math.floor(boundingBox.getMin().getZ() / PARTITION_SIZE_MAX);
int maxXPartition = (int) Math.floor(boundingBox.getMax().getX() / PARTITION_SIZE_MAX);
int maxYPartition = (int) Math.floor(boundingBox.getMax().getY() / PARTITION_SIZE_MAX);
int maxZPartition = (int) Math.floor(boundingBox.getMax().getZ() / PARTITION_SIZE_MAX);
for (int yPartition = minYPartition; yPartition <= maxYPartition; yPartition++) for (int xPartition = minXPartition; xPartition <= maxXPartition; xPartition++) for (int zPartition = minZPartition; zPartition <= maxZPartition; zPartition++) {
// try to find node by key
key.reset();
key.append(xPartition);
key.append(",");
key.append(yPartition);
key.append(",");
key.append(zPartition);
PartitionTreeNode node = treeRoot.subNodesByCoordinate.get(key);
if (node == null) {
node = createPartition(treeRoot, xPartition, yPartition, zPartition, PARTITION_SIZE_MAX);
}
}
// add entity to tree
addToPartitionTree(entity, boundingBox);
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class CollisionDetection method doCollide.
/**
* Checks if sphere collides with oriented bounding box
* @param sphere
* @param oriented bounding box
* @param movement
* @param collision
* @return collision
*/
public boolean doCollide(Sphere sphere, OrientedBoundingBox obb, Vector3 movement, CollisionResponse collision) {
//
collision.reset();
// do broad test
if (doBroadTest(sphere, obb) == false)
return false;
//
Vector3 sphereCenter = sphere.getCenter();
obb.computeClosestPointOnBoundingVolume(sphereCenter, closestPoint);
axis.set(closestPoint).sub(sphereCenter);
// check if to use movement fallback
float distance;
if (axis.computeLength() < MathTools.EPSILON) {
obb.computeNearestPointOnFaceBoundingVolume(closestPoint, pointOnFaceNearest);
obb.computeOppositePointOnFaceBoundingVolume(closestPoint, pointOnFaceOpposite);
obb.computeNearestPointOnFaceBoundingVolume(pointOnFaceNearest, closestPoint);
axis.set(sphereCenter).sub(pointOnFaceNearest);
distance = axis.computeLength() - sphere.getRadius();
axis.set(pointOnFaceOpposite).sub(pointOnFaceNearest);
} else {
//
distance = axis.computeLength() - sphere.getRadius();
}
if (distance < 0f) {
CollisionResponse.Entity collisionEntity = collision.addResponse(distance);
collisionEntity.getNormal().set(axis).normalize();
collisionEntity.addHitPoint(hitPoint.set(axis).normalize().scale(sphere.getRadius()).add(sphereCenter));
collisionEntity.addHitPoint(closestPoint);
if (CHECK_COLLISIONRESPONSE)
checkCollision(collision);
return true;
} else {
return false;
}
}
Aggregations