use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.
the class LodGenerator method computeEdgeCollapseCost.
float computeEdgeCollapseCost(Vertex src, Edge dstEdge) {
// This is based on Ogre's collapse cost calculation algorithm.
Vertex dest = dstEdge.destination;
// then this would destroy the shape, so don't do this
if (src.triangles.size() == 1 && dest.triangles.size() == 1) {
return NEVER_COLLAPSE_COST;
}
// Look for a face normal changing by > 90 degrees
for (Triangle triangle : src.triangles) {
// Ignore the deleted faces (those including src & dest)
if (!triangle.hasVertex(dest)) {
// Test the new face normal
Vertex pv0, pv1, pv2;
// Replace src with dest wherever it is
pv0 = (triangle.vertex[0] == src) ? dest : triangle.vertex[0];
pv1 = (triangle.vertex[1] == src) ? dest : triangle.vertex[1];
pv2 = (triangle.vertex[2] == src) ? dest : triangle.vertex[2];
// Cross-product 2 edges
tmpV1.set(pv1.position).subtractLocal(pv0.position);
tmpV2.set(pv2.position).subtractLocal(pv1.position);
//computing the normal
Vector3f newNormal = tmpV1.crossLocal(tmpV2);
newNormal.normalizeLocal();
// If < 0 then more than 90 degree difference
if (newNormal.dot(triangle.normal) < 0.0f) {
// Don't do it!
return NEVER_COLLAPSE_COST;
}
}
}
float cost;
// If we're looking at a border vertex
if (isBorderVertex(src)) {
if (dstEdge.refCount > 1) {
// src is on a border, but the src-dest edge has more than one tri on it
// So it must be collapsing inwards
// Mark as very high-value cost
// curvature = 1.0f;
cost = 1.0f;
} else {
// Collapsing ALONG a border
// We can't use curvature to measure the effect on the model
// Instead, see what effect it has on 'pulling' the other border edges
// The more colinear, the less effect it will have
// So measure the 'kinkiness' (for want of a better term)
// Find the only triangle using this edge.
// PMTriangle* triangle = findSideTriangle(src, dst);
cost = 0.0f;
Vector3f collapseEdge = tmpV1.set(src.position).subtractLocal(dest.position);
collapseEdge.normalizeLocal();
for (Edge edge : src.edges) {
Vertex neighbor = edge.destination;
//reference check intended
if (neighbor != dest && edge.refCount == 1) {
Vector3f otherBorderEdge = tmpV2.set(src.position).subtractLocal(neighbor.position);
otherBorderEdge.normalizeLocal();
// This time, the nearer the dot is to -1, the better, because that means
// the edges are opposite each other, therefore less kinkiness
// Scale into [0..1]
float kinkiness = (otherBorderEdge.dot(collapseEdge) + 1.002f) * 0.5f;
cost = Math.max(cost, kinkiness);
}
}
}
} else {
// not a border
// Standard inner vertex
// Calculate curvature
// use the triangle facing most away from the sides
// to determine our curvature term
// Iterate over src's faces again
cost = 0.001f;
for (Triangle triangle : src.triangles) {
// curve for face i and closer side to it
float mincurv = 1.0f;
for (Triangle triangle2 : src.triangles) {
if (triangle2.hasVertex(dest)) {
// Dot product of face normal gives a good delta angle
float dotprod = triangle.normal.dot(triangle2.normal);
// NB we do (1-..) to invert curvature where 1 is high curvature [0..1]
// Whilst dot product is high when angle difference is low
mincurv = Math.min(mincurv, (1.002f - dotprod) * 0.5f);
}
}
cost = Math.max(cost, mincurv);
}
}
// check for texture seam ripping
if (src.isSeam) {
if (!dest.isSeam) {
cost += meshBoundingSphereRadius;
} else {
cost += meshBoundingSphereRadius * 0.5;
}
}
return cost * src.position.distanceSquared(dest.position);
}
use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.
the class BoundingCollisionTest method testBoxBoxCollision.
@Test
public void testBoxBoxCollision() {
BoundingBox box1 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
BoundingBox box2 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
checkCollision(box1, box2, 1);
// Put it at the very edge - should still intersect.
box2.setCenter(new Vector3f(2f, 0f, 0f));
checkCollision(box1, box2, 1);
// Put it a wee bit farther - no intersection expected
box2.setCenter(new Vector3f(2f + FastMath.ZERO_TOLERANCE, 0, 0));
checkCollision(box1, box2, 0);
// Check the corners.
box2.setCenter(new Vector3f(2f, 2f, 2f));
checkCollision(box1, box2, 1);
box2.setCenter(new Vector3f(2f, 2f, 2f + FastMath.ZERO_TOLERANCE));
checkCollision(box1, box2, 0);
}
use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.
the class LightFilterTest method testPointFiltering.
@Test
public void testPointFiltering() {
PointLight pl = new PointLight(Vector3f.ZERO);
geom.addLight(pl);
// Infinite point lights must never be filtered
checkFilteredLights(1);
// Light at origin does not intersect geom which is at Z=10
pl.setRadius(1);
checkFilteredLights(0);
// Put it closer to geom, the very edge of the sphere touches the box.
// Still not considered an intersection though.
pl.setPosition(new Vector3f(0, 0, 8f));
checkFilteredLights(0);
// And more close - now its an intersection.
pl.setPosition(new Vector3f(0, 0, 8f + FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
// Move the geometry away
geom.move(0, 0, FastMath.ZERO_TOLERANCE);
checkFilteredLights(0);
// Test if the algorithm converts the sphere
// to a box before testing the collision (incorrect)
float sqrt3 = FastMath.sqrt(3);
pl.setPosition(new Vector3f(2, 2, 8));
pl.setRadius(sqrt3);
checkFilteredLights(0);
// Make it a wee bit larger.
pl.setRadius(sqrt3 + FastMath.ZERO_TOLERANCE);
checkFilteredLights(1);
// Rotate the camera so it is up, light is outside frustum.
cam.lookAtDirection(Vector3f.UNIT_Y, Vector3f.UNIT_Y);
checkFilteredLights(0);
// ==================================
// Tests for bounding Sphere
geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
geom.setLocalTranslation(0, 0, 2);
pl.setPosition(new Vector3f(0, 0, 2f));
// Infinite point lights must never be filtered
pl.setRadius(0);
checkFilteredLights(1);
pl.setRadius(1f);
// Put the light at the very close to the geom,
// the very edge of the sphere touches the other bounding sphere
// Still not considered an intersection though.
pl.setPosition(new Vector3f(0, 0, 0));
checkFilteredLights(0);
// And more close - now its an intersection.
pl.setPosition(new Vector3f(0, 0, 0f + FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
geom.setLocalTranslation(0, 0, 0);
// In this case its an intersection for pointLight v. box
// But not for pointLight v. sphere
// Vector3f(0, 0.5f, 0.5f).normalize().mult(2) ~ >= (0.0, 1.4142135, 1.4142135)
//pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 + FastMath.ZERO_TOLERANCE));
pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 + FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
// Make the distance a wee bit closer, now its an intersection
//pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 - FastMath.ZERO_TOLERANCE));
pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
checkFilteredLights(1);
// it's a point light, also test for the other corner
pl.setPosition(new Vector3f(0f, -1.4142135f, -1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
checkFilteredLights(0);
}
use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.
the class BoundingSphere method merge.
// /**
// * Merges this sphere with the given OBB.
// *
// * @param volume
// * The OBB to merge.
// * @return This sphere, after merging.
// */
// private BoundingSphere mergeOBB(OrientedBoundingBox volume) {
// // compute edge points from the obb
// if (!volume.correctCorners)
// volume.computeCorners();
// _mergeBuf.rewind();
// for (int i = 0; i < 8; i++) {
// _mergeBuf.put(volume.vectorStore[i].x);
// _mergeBuf.put(volume.vectorStore[i].y);
// _mergeBuf.put(volume.vectorStore[i].z);
// }
//
// // remember old radius and center
// float oldRadius = radius;
// Vector3f oldCenter = _compVect2.set( center );
//
// // compute new radius and center from obb points
// computeFromPoints(_mergeBuf);
// Vector3f newCenter = _compVect3.set( center );
// float newRadius = radius;
//
// // restore old center and radius
// center.set( oldCenter );
// radius = oldRadius;
//
// //merge obb points result
// merge( newRadius, newCenter, this );
//
// return this;
// }
private BoundingVolume merge(float temp_radius, Vector3f temp_center, BoundingSphere rVal) {
TempVars vars = TempVars.get();
Vector3f diff = temp_center.subtract(center, vars.vect1);
float lengthSquared = diff.lengthSquared();
float radiusDiff = temp_radius - radius;
float fRDiffSqr = radiusDiff * radiusDiff;
if (fRDiffSqr >= lengthSquared) {
if (radiusDiff <= 0.0f) {
vars.release();
return this;
}
Vector3f rCenter = rVal.center;
if (rCenter == null) {
rVal.setCenter(rCenter = new Vector3f());
}
rCenter.set(temp_center);
rVal.setRadius(temp_radius);
vars.release();
return rVal;
}
float length = (float) Math.sqrt(lengthSquared);
Vector3f rCenter = rVal.center;
if (rCenter == null) {
rVal.setCenter(rCenter = new Vector3f());
}
if (length > RADIUS_EPSILON) {
float coeff = (length + radiusDiff) / (2.0f * length);
rCenter.set(center.addLocal(diff.multLocal(coeff)));
} else {
rCenter.set(center);
}
rVal.setRadius(0.5f * (length + radius + temp_radius));
vars.release();
return rVal;
}
Aggregations