use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class EmptyView method updateGUIElements.
/**
* Init GUI elements
*/
public void updateGUIElements() {
if (entity != null) {
emptyScreenController.setScreenCaption("Empty - " + entity.getName());
PropertyModelClass preset = entity.getProperty("preset");
emptyScreenController.setEntityProperties(preset != null ? preset.getValue() : null, entity.getProperties(), null);
emptyScreenController.setEntityData(entity.getName(), entity.getDescription());
// trigger
Vector3 dimension = new Vector3();
dimension.set(entity.getModel().getBoundingBox().getMax());
dimension.sub(entity.getModel().getBoundingBox().getMin());
} else {
emptyScreenController.setScreenCaption("Empty - no trigger loaded");
emptyScreenController.unsetEntityProperties();
emptyScreenController.unsetEntityData();
}
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class World method determineHeight.
/**
* Determine height on x,y,u while respecting step up max
* @param type ids
* @param step up max
* @param point on which height should be calculated
* @param point where height has been determined
* @return rigid body from which height was determined or null
*/
public RigidBody determineHeight(int typeIds, float stepUpMax, Vector3 point, Vector3 dest) {
dest.set(point);
float[] pointXYZ = point.getArray();
// height bounding box to determine partition bounding volumes
heightBoundingBox.getMin().set(pointXYZ[0], -10000f, pointXYZ[2]);
heightBoundingBox.getMax().set(pointXYZ[0], +10000f, pointXYZ[2]);
heightBoundingBox.update();
// determine height of point on x, z
heightOnPointCandidate.set(pointXYZ[0], 10000f, pointXYZ[2]);
float height = -10000f;
RigidBody heightRigidBody = null;
for (RigidBody rigidBody : partition.getObjectsNearTo(heightBoundingBox)) {
if (((rigidBody.typeId & typeIds) == rigidBody.typeId) == false)
continue;
BoundingVolume cbv = rigidBody.cbv;
if (cbv instanceof BoundingBox) {
if (heightOnPointLineSegment.doesBoundingBoxCollideWithLineSegment((BoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else if (cbv instanceof OrientedBoundingBox) {
if (heightOnPointLineSegment.doesOrientedBoundingBoxCollideWithLineSegment((OrientedBoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else {
// compute closest point on height candidate
cbv.computeClosestPointOnBoundingVolume(heightOnPointCandidate, heightOnPointA);
// check new height, take only result into account which is near to candidate
if (Math.abs(heightOnPointCandidate.getX() - heightOnPointA.getX()) < 0.1f && Math.abs(heightOnPointCandidate.getZ() - heightOnPointA.getZ()) < 0.1f && heightOnPointA.getY() >= height && heightOnPointA.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPointA.getY();
heightRigidBody = rigidBody;
}
}
}
// check if we have a ground
if (heightRigidBody == null) {
return null;
}
// nope, no collision
dest.setY(height);
return heightRigidBody;
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class BoundingBox method fromBoundingVolumeWithTransformations.
/*
* (non-Javadoc)
* @see net.drewke.tdme.primitives.BoundingVolume#fromBoundingVolumeWithTransformations(net.drewke.tdme.primitives.BoundingVolume, net.drewke.tdme.engine.Transformations)
*/
public void fromBoundingVolumeWithTransformations(BoundingVolume original, Transformations transformations) {
// check for same type of original
if (original instanceof BoundingBox == false) {
System.out.println("BoundingBox::fromBoundingVolumeWithTransformations(): original is not of same type");
return;
}
//
BoundingBox boundingBox = (BoundingBox) original;
//
Matrix4x4 transformationsMatrix = transformations.getTransformationsMatrix();
Vector3[] _vertices = boundingBox.getVertices();
// apply transformations from original vertices to local vertices
for (int i = 0; i < vertices.length; i++) {
transformationsMatrix.multiply(_vertices[i], vertices[i]);
}
// determine axis aligned bounding box constraints based on local vertices
float[] vertexXYZ = vertices[0].getArray();
float minX = vertexXYZ[0], minY = vertexXYZ[1], minZ = vertexXYZ[2];
float maxX = vertexXYZ[0], maxY = vertexXYZ[1], maxZ = vertexXYZ[2];
for (int vertexIndex = 1; vertexIndex < vertices.length; vertexIndex++) {
Vector3 vertex = vertices[vertexIndex];
vertexXYZ = vertex.getArray();
if (vertexXYZ[0] < minX)
minX = vertexXYZ[0];
if (vertexXYZ[1] < minY)
minY = vertexXYZ[1];
if (vertexXYZ[2] < minZ)
minZ = vertexXYZ[2];
if (vertexXYZ[0] > maxX)
maxX = vertexXYZ[0];
if (vertexXYZ[1] > maxY)
maxY = vertexXYZ[1];
if (vertexXYZ[2] > maxZ)
maxZ = vertexXYZ[2];
}
// set up new aabb
min.set(minX, minY, minZ);
max.set(maxX, maxY, maxZ);
// compute new vertices based on aabb constraints
update();
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class LineSegment method doesOrientedBoundingBoxCollideWithLineSegment.
/**
* Check if segment collides with oriented bounding box
* based on an algorithm from "Real-Time Collision Detection" / Ericson
* Credit:
* "From Real-Time Collision Detection by Christer Ericson
* published by Morgan Kaufman Publishers, (c) 2005 Elsevier Inc"
* @param oriented bounding box
* @param point p on line segment
* @param point q on line segment
* @param contact point min
* @param contact point max
* @return true if collides or false if not
*/
public boolean doesOrientedBoundingBoxCollideWithLineSegment(OrientedBoundingBox orientedBoundingBox, Vector3 p, Vector3 q, Vector3 contactMin, Vector3 contactMax) {
float tmin = 0.0f;
float tmax = 1.0f;
Vector3[] obbAxes = orientedBoundingBox.axes;
Vector3 obbCenter = orientedBoundingBox.center;
Vector3 obbHalfExtension = orientedBoundingBox.halfExtension;
float[] obbHalfExtensionXYZ = obbHalfExtension.getArray();
direction.set(q).sub(p);
for (int i = 0; i < 3; i++) {
float directionLengthOnAxis = Vector3.computeDotProduct(direction, obbAxes[i]);
float obbExtensionLengthOnAxis = obbHalfExtensionXYZ[i];
float obbCenterLengthOnAxis = Vector3.computeDotProduct(obbCenter, obbAxes[i]);
float pointLengthOnAxis = Vector3.computeDotProduct(p, obbAxes[i]);
if (Math.abs(directionLengthOnAxis) < MathTools.EPSILON && (pointLengthOnAxis <= obbCenterLengthOnAxis - obbExtensionLengthOnAxis || pointLengthOnAxis >= obbCenterLengthOnAxis + obbExtensionLengthOnAxis)) {
return false;
} else {
float odd = 1.0f / directionLengthOnAxis;
float t1 = (obbCenterLengthOnAxis - obbExtensionLengthOnAxis - pointLengthOnAxis) * odd;
float t2 = (obbCenterLengthOnAxis + obbExtensionLengthOnAxis - pointLengthOnAxis) * odd;
if (t1 > t2) {
float tmp = t1;
t1 = t2;
t2 = tmp;
}
tmin = Math.max(tmin, t1);
tmax = Math.min(tmax, t2);
if (tmin > tmax)
return false;
}
}
//
if (tmin > 1.0)
return false;
// compute contact points
contactMin.set(p).add(d1.set(direction).scale(tmin));
contactMax.set(p).add(d2.set(direction).scale(tmax));
// we have a collision
return true;
}
use of net.drewke.tdme.math.Vector3 in project tdme by andreasdr.
the class ModelUtilitiesInternal method createBoundingBox.
/**
* Creates a bounding box from given object3d model
* @param model
* @return axis aligned bounding box
*/
public static BoundingBox createBoundingBox(Object3DModelInternal object3DModelInternal) {
Model model = object3DModelInternal.getModel();
AnimationSetup defaultAnimation = model.getAnimationSetup(Model.ANIMATIONSETUP_DEFAULT);
//
float minX = 0f, minY = 0f, minZ = 0f;
float maxX = 0f, maxY = 0f, maxZ = 0f;
boolean firstVertex = true;
// create bounding box for whole animation at 60fps
AnimationState animationState = new AnimationState();
animationState.setup = defaultAnimation;
animationState.lastAtTime = Timing.UNDEFINED;
animationState.currentAtTime = 0L;
animationState.time = 0.0f;
animationState.finished = false;
for (float t = 0.0f; t <= (defaultAnimation != null ? defaultAnimation.getFrames() : 0.0f) / model.getFPS(); t += 1f / model.getFPS()) {
//
// calculate transformations matrices without world transformations
object3DModelInternal.computeTransformationsMatrices(model.getSubGroups(), object3DModelInternal.getModel().getImportTransformationsMatrix().clone().multiply(object3DModelInternal.getTransformationsMatrix()), animationState, 0);
Object3DGroup.computeTransformations(object3DModelInternal.object3dGroups, object3DModelInternal.transformationsMatrices);
// parse through object groups to determine min, max
for (Object3DGroup object3DGroup : object3DModelInternal.object3dGroups) {
for (Vector3 vertex : object3DGroup.mesh.transformedVertices) {
// vertex xyz array
float[] vertexXYZ = vertex.getArray();
// determine min, max
if (firstVertex == true) {
minX = vertexXYZ[0];
minY = vertexXYZ[1];
minZ = vertexXYZ[2];
maxX = vertexXYZ[0];
maxY = vertexXYZ[1];
maxZ = vertexXYZ[2];
firstVertex = false;
} else {
if (vertexXYZ[0] < minX)
minX = vertexXYZ[0];
if (vertexXYZ[1] < minY)
minY = vertexXYZ[1];
if (vertexXYZ[2] < minZ)
minZ = vertexXYZ[2];
if (vertexXYZ[0] > maxX)
maxX = vertexXYZ[0];
if (vertexXYZ[1] > maxY)
maxY = vertexXYZ[1];
if (vertexXYZ[2] > maxZ)
maxZ = vertexXYZ[2];
}
}
}
animationState.currentAtTime = (long) (t * 1000f);
animationState.lastAtTime = (long) (t * 1000f);
}
// skip on models without meshes to be rendered
if (firstVertex == true)
return null;
// otherwise go with bounding box
return new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ));
}
Aggregations