@Override public double getRadius() { double radius = 0.0; radius = Math.max(radius, _xAxis.multiply(_extent.getX(), _compVect1).length()); radius = Math.max(radius, _yAxis.multiply(_extent.getY(), _compVect1).length()); radius = Math.max(radius, _zAxis.multiply(_extent.getZ(), _compVect1).length()); return radius; }
/** * Calculates the minimum bounding sphere of 3 points. Used in welzl's algorithm. * * @param O * The 1st point inside the sphere. * @param A * The 2nd point inside the sphere. * @param B * The 3rd point inside the sphere. * @see #calcWelzl(java.nio.FloatBuffer) */ private void setSphere(final Vector3 O, final Vector3 A, final Vector3 B) { final Vector3 a = A.subtract(O, null); final Vector3 b = B.subtract(O, null); final Vector3 acrossB = a.cross(b, null); final double Denominator = 2.0 * acrossB.dot(acrossB); if (Denominator == 0) { _center.set(0, 0, 0); setRadius(0); } else { final Vector3 o = acrossB.cross(a, null).multiplyLocal(b.lengthSquared()) .addLocal(b.cross(acrossB, null).multiplyLocal(a.lengthSquared())).divideLocal(Denominator); setRadius(o.length() * radiusEpsilon); O.add(o, _center); } }
@Override public double getRadius() { double radius = 0.0; radius = Math.max(radius, _xAxis.multiply(_extent.getX(), _compVect1).length()); radius = Math.max(radius, _yAxis.multiply(_extent.getY(), _compVect1).length()); radius = Math.max(radius, _zAxis.multiply(_extent.getZ(), _compVect1).length()); return radius; }
/** * Calculates the minimum bounding sphere of 3 points. Used in welzl's algorithm. * * @param O * The 1st point inside the sphere. * @param A * The 2nd point inside the sphere. * @param B * The 3rd point inside the sphere. * @see #calcWelzl(java.nio.FloatBuffer) */ private void setSphere(final Vector3 O, final Vector3 A, final Vector3 B) { final Vector3 a = A.subtract(O, null); final Vector3 b = B.subtract(O, null); final Vector3 acrossB = a.cross(b, null); final double Denominator = 2.0 * acrossB.dot(acrossB); if (Denominator == 0) { _center.set(0, 0, 0); setRadius(0); } else { final Vector3 o = acrossB.cross(a, null).multiplyLocal(b.lengthSquared()) .addLocal(b.cross(acrossB, null).multiplyLocal(a.lengthSquared())).divideLocal(Denominator); setRadius(o.length() * radiusEpsilon); O.add(o, _center); } }
private boolean shouldDoUpdate(final Camera cam) { if (_redrawRate > 0 && _elapsed >= _redrawRate) { _elapsed = _elapsed % _redrawRate; return true; } if (_cameraAngleThreshold > 0) { _tempVec.set(_center).subtractLocal(cam.getLocation()); final double currentDist = _tempVec.length(); if (_lastCamDist != 0 && Math.abs(currentDist - _lastCamDist) / _lastCamDist > _cameraDistanceThreshold) { return true; } _tempVec.normalizeLocal(); final double angle = _tempVec.smallestAngleBetween(_lastCamDir); if (angle > _cameraAngleThreshold) { return true; } } return false; }
private boolean shouldDoUpdate(final Camera cam) { if (_redrawRate > 0 && _elapsed >= _redrawRate) { _elapsed = _elapsed % _redrawRate; return true; } if (_cameraAngleThreshold > 0) { _tempVec.set(_center).subtractLocal(cam.getLocation()); final double currentDist = _tempVec.length(); if (_lastCamDist != 0 && Math.abs(currentDist - _lastCamDist) / _lastCamDist > _cameraDistanceThreshold) { return true; } _tempVec.normalizeLocal(); final double angle = _tempVec.smallestAngleBetween(_lastCamDir); if (angle > _cameraAngleThreshold) { return true; } } return false; }
protected double calculateHandleScale(final InteractManager manager) { final Spatial target = manager.getSpatialTarget(); if (target != null && target.getWorldBound() != null) { final BoundingVolume bound = target.getWorldBound(); final ReadOnlyVector3 trans = target.getWorldTranslation(); return Math.max(AbstractInteractWidget.MIN_SCALE, bound.getRadius() + trans.subtract(bound.getCenter(), _calcVec3A).length()); } return 1.0; }
/** * Constructs a new segment segment using the supplied start and end points * * @param start * @param end */ public LineSegment3(final ReadOnlyVector3 start, final ReadOnlyVector3 end) { this(); _origin.set(start).addLocal(end).multiplyLocal(0.5); _direction.set(end).subtractLocal(start); _extent = 0.5 * _direction.length(); _direction.normalizeLocal(); }
/** * Constructs a new segment segment using the supplied start and end points * * @param start * @param end */ public LineSegment3(final ReadOnlyVector3 start, final ReadOnlyVector3 end) { this(); _origin.set(start).addLocal(end).multiplyLocal(0.5); _direction.set(end).subtractLocal(start); _extent = 0.5 * _direction.length(); _direction.normalizeLocal(); }
@Override // XXX: HACK, revisit. public BoundingVolume transform(final ReadOnlyTransform transform, BoundingVolume store) { if (store == null || store.getType() != Type.OBB) { store = new OrientedBoundingBox(); } final OrientedBoundingBox toReturn = (OrientedBoundingBox) store; final Vector3 helper = new Vector3(); helper.set(1, 0, 0); final double scaleX = transform.applyForwardVector(helper).length(); helper.set(0, 1, 0); final double scaleY = transform.applyForwardVector(helper).length(); helper.set(0, 0, 1); final double scaleZ = transform.applyForwardVector(helper).length(); toReturn._extent.set(Math.abs(_extent.getX() * scaleX), Math.abs(_extent.getY() * scaleY), Math.abs(_extent.getZ() * scaleZ)); transform.getMatrix().applyPost(_xAxis, toReturn._xAxis); transform.getMatrix().applyPost(_yAxis, toReturn._yAxis); transform.getMatrix().applyPost(_zAxis, toReturn._zAxis); if (!transform.isRotationMatrix()) { toReturn._xAxis.normalizeLocal(); toReturn._yAxis.normalizeLocal(); toReturn._zAxis.normalizeLocal(); } transform.applyForward(_center, toReturn._center); toReturn.correctCorners = false; toReturn.computeCorners(); return toReturn; }
@Override // XXX: HACK, revisit. public BoundingVolume transform(final ReadOnlyTransform transform, BoundingVolume store) { if (store == null || store.getType() != Type.OBB) { store = new OrientedBoundingBox(); } final OrientedBoundingBox toReturn = (OrientedBoundingBox) store; final Vector3 helper = new Vector3(); helper.set(1, 0, 0); final double scaleX = transform.applyForwardVector(helper).length(); helper.set(0, 1, 0); final double scaleY = transform.applyForwardVector(helper).length(); helper.set(0, 0, 1); final double scaleZ = transform.applyForwardVector(helper).length(); toReturn._extent.set(Math.abs(_extent.getX() * scaleX), Math.abs(_extent.getY() * scaleY), Math.abs(_extent.getZ() * scaleZ)); transform.getMatrix().applyPost(_xAxis, toReturn._xAxis); transform.getMatrix().applyPost(_yAxis, toReturn._yAxis); transform.getMatrix().applyPost(_zAxis, toReturn._zAxis); if (!transform.isRotationMatrix()) { toReturn._xAxis.normalizeLocal(); toReturn._yAxis.normalizeLocal(); toReturn._zAxis.normalizeLocal(); } transform.applyForward(_center, toReturn._center); toReturn.correctCorners = false; toReturn.computeCorners(); return toReturn; }
@Override public void apply(final double dt, final Particle particle, final int index) { if (_wanderRadius == 0 && _wanderDistance == 0 && _wanderJitter == 0) { return; } final Vector3 wanderTarget = _wanderTargets.get(index); wanderTarget.addLocal(calcNewJitter(), calcNewJitter(), calcNewJitter()); wanderTarget.normalizeLocal(); wanderTarget.multiplyLocal(_wanderRadius); _workVect.set(particle.getVelocity()).normalizeLocal().multiplyLocal(_wanderDistance); _workVect.addLocal(wanderTarget).normalizeLocal(); _workVect.multiplyLocal(particle.getVelocity().length()); particle.getVelocity().set(_workVect); }
@Override public void apply(final double dt, final Particle particle, final int index) { if (_wanderRadius == 0 && _wanderDistance == 0 && _wanderJitter == 0) { return; } final Vector3 wanderTarget = _wanderTargets.get(index); wanderTarget.addLocal(calcNewJitter(), calcNewJitter(), calcNewJitter()); wanderTarget.normalizeLocal(); wanderTarget.multiplyLocal(_wanderRadius); _workVect.set(particle.getVelocity()).normalizeLocal().multiplyLocal(_wanderDistance); _workVect.addLocal(wanderTarget).normalizeLocal(); _workVect.multiplyLocal(particle.getVelocity().length()); particle.getVelocity().set(_workVect); }
final Vector3 temp_center = box._center; _compVect1.set(box.getXExtent(), box.getYExtent(), box.getZExtent()); final double radius = _compVect1.length(); return merge(radius, temp_center, this);
@Override public void apply(final double dt, final Particle particle, final int index) { // Is particle alive, AND "under" our floor? if (particle.getStatus() == Particle.Status.Alive && _floor.pseudoDistance(particle.getPosition()) <= 0) { final Vector3 tempVect1 = Vector3.fetchTempInstance(); final double scale = particle.getVelocity().length(); tempVect1.set(particle.getVelocity()).divideLocal(scale); // normalize // Is the particle moving further into the floor? if (_floor.getNormal().smallestAngleBetween(tempVect1) > MathUtils.HALF_PI) { // reflect our velocity vector across the floor plane _floor.reflectVector(tempVect1, tempVect1); // apply the "bounciness" factor tempVect1.multiplyLocal(scale * _bounciness); // write back to particle particle.setVelocity(tempVect1); } Vector3.releaseTempInstance(tempVect1); } }
@Override public void apply(final double dt, final Particle particle, final int index) { // Is particle alive, AND "under" our floor? if (particle.getStatus() == Particle.Status.Alive && _floor.pseudoDistance(particle.getPosition()) <= 0) { final Vector3 tempVect1 = Vector3.fetchTempInstance(); final double scale = particle.getVelocity().length(); tempVect1.set(particle.getVelocity()).divideLocal(scale); // normalize // Is the particle moving further into the floor? if (_floor.getNormal().smallestAngleBetween(tempVect1) > MathUtils.HALF_PI) { // reflect our velocity vector across the floor plane _floor.reflectVector(tempVect1, tempVect1); // apply the "bounciness" factor tempVect1.multiplyLocal(scale * _bounciness); // write back to particle particle.setVelocity(tempVect1); } Vector3.releaseTempInstance(tempVect1); } }
@Override public void apply(final double dt, final Particle p, final int index) { final double dtStr = dt * _strength * (_random ? MathUtils.nextRandomFloat() : 1f); p.getPosition().subtract(_line.getOrigin(), _v1); _line.getDirection().cross(_v1, v2); if (v2.length() == 0) { // particle is on the axis return; } v2.normalizeLocal(); if (_type == VT_CYLINDER) { _rot.apply(v2, v2); v2.scaleAdd(dtStr, p.getVelocity(), p.getVelocity()); return; } v2.cross(_line.getDirection(), _v1); _v1.multiplyLocal(_radius); _line.getDirection().scaleAdd(_height, _v1, _v1); _v1.addLocal(_line.getOrigin()); _v1.subtractLocal(p.getPosition()); if (_v1.length() == 0) { // particle is on the ring return; } _v1.normalizeLocal(); _v1.cross(v2, v3); _rot.fromAngleAxis(-_divergence, v2); _rot.apply(v3, v3); v3.scaleAdd(dtStr, p.getVelocity(), p.getVelocity()); }
@Test public void testNormalize() { final Vector3 vec1 = new Vector3(2, 1, 3); assertTrue(vec1.length() == Math.sqrt(14)); final Vector3 vec2 = vec1.normalize(null); final double invLength = MathUtils.inverseSqrt(2 * 2 + 1 * 1 + 3 * 3); assertEquals(new Vector3(2 * invLength, 1 * invLength, 3 * invLength), vec2); vec1.normalizeLocal(); assertEquals(new Vector3(2 * invLength, 1 * invLength, 3 * invLength), vec1); vec1.zero(); vec1.normalize(vec2); assertEquals(vec1, vec2); // ensure no exception thrown vec1.normalizeLocal(); vec1.normalize(null); }