public double f1(Vector3f point, Vector3f A, Vector3f B) { // ****** basic parameters ****** Vector3f vec_b = B; Vector3f vec_a = A.subtract(vec_b); Vector3f vec_r = point; double L = vec_a.length(); Vector3f vec_d = vec_r.subtract(vec_b); double d = vec_d.length(); double h = vec_d.dot(vec_a.normalize()); // terms double s2 = s * s; double h2 = h * h; double lmh = L - h; double d2 = d * d; double p2 = 1 + s2 * (d2 - h2); double p = Math.sqrt(p2); double ww = p2 + s2 * h2; double qq = p2 + s2 * lmh * lmh; double sdp = s / p; double tpp = 2.0 * p2; double sp = s * p; double term = Math.atan(sdp * h) + Math.atan(sdp * lmh); return (h / ww + lmh / qq) / tpp + term / (tpp * sp); }
public Vector3f calculateForce( Vector3f location, Vector3f velocity, float collisionRadius, float speed, float turnSpeed, float tpf, List<Obstacle> obstacles) { float cautionRange = speed * 1.5f / turnSpeed; Line line = new Line(location, velocity.normalize()); Plane plane = new Plane(velocity, 1); Vector3f closest = Vector3f.ZERO; float shortestDistance = -1; for (Obstacle obs : obstacles) { Vector3f target = obs.getLocation(); Vector3f loc = target.subtract(location); // If the obstacle isn't ahead of him, just ignore it if (plane.whichSide(loc) != Side.Positive) { continue; } // Check if the target is inside the check range if (location.distance(target) <= collisionRadius + cautionRange + obs.getRadius()) { // Check if the target will collide with the source if (obs.distance(line) < collisionRadius) { float newDistance = obs.distance(location); // Store the closest target if (shortestDistance == -1 || newDistance < shortestDistance) shortestDistance = newDistance; closest = target; } } } // If any target was found if (shortestDistance != -1) { // Find in wich side the target is // To do that, we do a signed distance by // subtracing the location from the target // and the dot product between the line's normal float dot = closest.subtract(location).dot(line.getDirection().cross(Vector3f.UNIT_Y)); if (dot <= 0) return velocity.cross(Vector3f.UNIT_Y); else return velocity.cross(Vector3f.UNIT_Y).negate(); } // No target found, just return a zero value return Vector3f.ZERO; }
public void setCameraPosition(Vector3f position) { // get vector between planet and camera this.planetToCamera = position.subtract(this.getWorldTranslation()); // get distance to surface this.distanceToCamera = this.planetToCamera.length() - this.baseRadius; // are we in the atmosphere? if (this.atmosphereNode != null) { if (this.distanceToCamera < this.atmosphereRadius - this.baseRadius) { this.previouslyInAtmosphere = this.currentlyInAtmosphere; this.currentlyInAtmosphere = true; } else { this.previouslyInAtmosphere = this.currentlyInAtmosphere; this.currentlyInAtmosphere = false; } } // are we in the water? if (this.oceanNode != null) { if (this.distanceToCamera <= 1f) { this.previouslyInOcean = this.currentlyInOcean; this.currentlyInOcean = true; } else { this.previouslyInOcean = this.currentlyInOcean; this.currentlyInOcean = false; } } // Update camera positions for all quads int currentTerrainMaxDepth = 0; for (int i = 0; i < 6; i++) { if (terrainSide[i] != null) { terrainSide[i].setCameraPosition(position); // get current max depth of quad for skirt toggling currentTerrainMaxDepth = Math.max(currentTerrainMaxDepth, terrainSide[i].getCurrentMaxDepth()); } if (oceanSide[i] != null) { oceanSide[i].setCameraPosition(position); } if (atmosphereSide[i] != null) { atmosphereSide[i].setCameraPosition(position); } } // toggle skirting on the terrain if needed boolean skirting; // Are we at minDepth? if (currentTerrainMaxDepth == this.minDepth) { // Turn off skirting if entire terrain is at minDepth skirting = false; } else { // otherwise turn on skirting skirting = true; } // Go through and set skirting on all terrain quads for (int i = 0; i < 6; i++) { if (terrainSide[i] != null) terrainSide[i].setSkirting(skirting); } }
@Override public void update(float tpf) { if (forward ^ backward) { // float yCoord = charControl.getRigidBody().getLinearVelocity().getY(); Vector3f charLocation = charControl.getPhysicsLocation(); Vector3f walkDir = charLocation .subtract(app.getCamera().getLocation().clone().setY(charLocation.getY())) .normalizeLocal(); if (backward) { walkDir.negateLocal(); } charControl.setWalkDirection(walkDir); charControl.setMove(true); } else { charControl.setMove(false); } if (jump) { charControl.setJump(); jump = false; } Vector3f camdir = app.getCamera().getDirection().clone(); Quaternion newRot = new Quaternion(); newRot.lookAt(camdir.setY(0), Vector3f.UNIT_Y); charControl.setRotationInUpdate(newRot); }
public double flt(Vector3f point, Vector3f A, Vector3f B) { Vector3f vec_b = B; Vector3f vec_a = A.subtract(vec_b); double L = vec_a.length(); return L * f1(point, A, B) - ft(point, A, B); }
@SuppressWarnings("unused") private double cauchy(Vector3f point, Vector3f center) { Vector3f vec_r = point.subtract(center); double s = 0.85; // 0.85 - example on thesis; //kernel width double r_2 = vec_r.lengthSquared(); return 1.0 / ((1 + s * s * r_2) * (1 + s * s * r_2)); }
public Bullet( SimpleApplication sa, Vector3f bulletWorldTranslation, Vector3f tankWorldTranslation) { this.sa = sa; this.position = bulletWorldTranslation; this.tankWorldTranslation = tankWorldTranslation; velocity = position.subtract(tankWorldTranslation).subtract(new Vector3f(0, 2f, 0)).mult(1.2f); initBullet(); }
/** * Centers the spatial in the origin of the world bound. * * @return The spatial on which this method is called, e.g <code>this</code>. */ public Spatial center() { Vector3f worldTrans = getWorldTranslation(); Vector3f worldCenter = getWorldBound().getCenter(); Vector3f absTrans = worldTrans.subtract(worldCenter); setLocalTranslation(absTrans); return this; }
/** * Using this slot's camera, construct a pick ray for the specified screen coordinates. * * @param screenLocation screen coordinates (in pixels, measured from the lower left, not null, * unaffected) * @return new instance */ @Override public Ray pickRay(Vector2f screenLocation) { Validate.nonNull(screenLocation, "screen location"); Vector3f startLocation = cam.getWorldCoordinates(screenLocation, 0f); Vector3f farPoint = cam.getWorldCoordinates(screenLocation, 1f); Vector3f direction = farPoint.subtract(startLocation).normalizeLocal(); Ray result = new Ray(startLocation, direction); return result; }
public double ft(Vector3f point, Vector3f A, Vector3f B) { // ****** basic parameters ****** Vector3f vec_b = B; Vector3f vec_a = A.subtract(vec_b); Vector3f vec_r = point; double L = vec_a.length(); Vector3f vec_d = vec_r.subtract(vec_b); double d = vec_d.length(); double h = vec_d.dot(vec_a.normalize()); // terms double s2 = s * s; double h2 = h * h; double lmh = L - h; double d2 = d * d; double p2 = 1 + s2 * (d2 - h2); double ww = p2 + s2 * h2; double qq = p2 + s2 * lmh * lmh; double ts2 = 2.0 * s2; return h * f1(point, A, B) + (1.0 / ww - 1.0 / qq) / ts2; }
/** * Compute bounds from an array of points * * @param pts * @param transform * @return */ public static BoundingBox computeBoundForPoints(Vector3f[] pts, Transform transform) { Vector3f min = new Vector3f(Vector3f.POSITIVE_INFINITY); Vector3f max = new Vector3f(Vector3f.NEGATIVE_INFINITY); Vector3f temp = new Vector3f(); for (int i = 0; i < pts.length; i++) { transform.transformVector(pts[i], temp); min.minLocal(temp); max.maxLocal(temp); } Vector3f center = min.add(max).multLocal(0.5f); Vector3f extent = max.subtract(min).multLocal(0.5f); return new BoundingBox(center, extent.x, extent.y, extent.z); }
void lookAt(Vector3f pos) { Vector3f location = spatial.getLocalTranslation(); Vector3f target = pos.clone(); Vector3f distance = target.subtract(location); if (distance.length() < 0.3f) { return; } Vector3f newVel = distance.normalize(); Quaternion q = new Quaternion(); q.lookAt(newVel, Vector3f.UNIT_Y); // q.addLocal(playerInfo.initalRot); spatial.setLocalRotation(q); }
void moveTo(Vector3f pos) { float speed = playerInfo.getRealSpeed(); Vector3f location = spatial.getLocalTranslation(); Vector3f target = pos.clone(); Vector3f distance = target.subtract(location); if (distance.length() < 0.3f) { return; } Vector3f newVel = distance.normalize().mult(speed); // Vector3f steering = desierdVel.subtract(velocity).negate(); spatial.setLocalTranslation(location.add(newVel)); }
private void refreshFont() { Camera cam = IsoCamera.getInstance().getCam(); Vector3f start = from.getPlanet().getPosition(); Vector3f end = to.getPlanet().getPosition(); float width = label.getLineWidth(); Random r = new Random(); // float height = r.nextFloat() * end.subtract(start).z; Vector3f position = new Vector3f(width / 2, .15f, 0); Vector3f fontPos = start.add(end.subtract(start).mult(0.4f + 0.75f * r.nextFloat())); position.addLocal(fontPos); Vector3f up = cam.getUp().clone(); Vector3f dir = cam.getDirection().clone().negateLocal().normalizeLocal(); Vector3f left = cam.getLeft().clone().normalizeLocal().negateLocal(); Quaternion look = new Quaternion(); look.fromAxes(left, up, dir); label.setLocalTransform(new Transform(position, look)); // Vector3f camPos = IsoCamera.getInstance().getCam().getLocation(); // Vector3f fontPos = to.getPlanet().getPosition(). // subtract(from.getPlanet().getPosition()); // Vector3f up = IsoCamera.getInstance().getCam().getUp().clone(); // Vector3f dir = camPos.subtract(fontPos); //// Vector3f dir = Vector3f.UNIT_Y.clone().subtract(fontPos); // // Vector3f left = IsoCamera.getInstance().getCam().getLeft().clone(); // dir.normalizeLocal(); // left.negateLocal(); // left.normalizeLocal(); // up.normalizeLocal(); //// dir.negateLocal(); // // Quaternion look = new Quaternion(); // look.fromAxes(left, up, dir); // // Vector3f newPos = to.getPlanet().getPosition(). // subtract(from.getPlanet().getPosition()); // // newPos.x -= label.getLineWidth() / 2; // // Transform t = new Transform(newPos, look); // // label.setLocalTransform(t); }
public void locationChecker(Monster monster) { Vector3f playerLocation = player.Model.getLocalTranslation(); Vector3f monsterLocation = monster.Model.getLocalTranslation(); float distance = playerLocation.distance(monsterLocation); Vector3f playerDirection = playerLocation.subtract(monsterLocation); monsterRotater(monster, playerDirection); if (distance < 3) { if (monster.attackDelay == 10) { monster.attackDelay = 0; monster.attack(monster.Model, player); } else { monster.attackDelay++; } } else { monster.anim.animChange("UnarmedRun", "RunAction", monster.Model); } }
public float getHeadingAtWP(int index) { float heading = 0; Waypoint nextWayPoint = getNextWayPoint(index); // if next way point available, compute heading towards it if (nextWayPoint != null) { // compute driving direction by looking at next way point from current position Vector3f targetPosition = nextWayPoint.getPosition().clone(); targetPosition.setY(0); Vector3f currentPosition = waypointList.get(index).getPosition().clone(); currentPosition.setY(0); Vector3f drivingDirection = targetPosition.subtract(currentPosition).normalize(); // compute heading (orientation) from driving direction vector for // angle between driving direction and heading "0" float angle0 = drivingDirection.angleBetween(new Vector3f(0, 0, -1)); // angle between driving direction and heading "90" float angle90 = drivingDirection.angleBetween(new Vector3f(1, 0, 0)); // get all candidates for heading // find the value from {heading1,heading2} which matches with one of {heading3,heading4} float heading1 = (2.0f * FastMath.PI + angle0) % FastMath.TWO_PI; float heading2 = (2.0f * FastMath.PI - angle0) % FastMath.TWO_PI; float heading3 = (2.5f * FastMath.PI + angle90) % FastMath.TWO_PI; float heading4 = (2.5f * FastMath.PI - angle90) % FastMath.TWO_PI; float diff_1_3 = FastMath.abs(heading1 - heading3); float diff_1_4 = FastMath.abs(heading1 - heading4); float diff_2_3 = FastMath.abs(heading2 - heading3); float diff_2_4 = FastMath.abs(heading2 - heading4); if ((diff_1_3 < diff_1_4 && diff_1_3 < diff_2_3 && diff_1_3 < diff_2_4) || (diff_1_4 < diff_1_3 && diff_1_4 < diff_2_3 && diff_1_4 < diff_2_4)) { // if diff_1_3 or diff_1_4 are smallest --> the correct heading is heading1 heading = heading1; } else { // if diff_2_3 or diff_2_4 are smallest --> the correct heading is heading2 heading = heading2; } } return heading; }
/** * Compute bounds from an array of points * * @param pts * @param mat * @return */ public static BoundingBox computeBoundForPoints(Vector3f[] pts, Matrix4f mat) { Vector3f min = new Vector3f(Vector3f.POSITIVE_INFINITY); Vector3f max = new Vector3f(Vector3f.NEGATIVE_INFINITY); Vector3f temp = new Vector3f(); for (int i = 0; i < pts.length; i++) { float w = mat.multProj(pts[i], temp); temp.x /= w; temp.y /= w; // Why was this commented out? temp.z /= w; min.minLocal(temp); max.maxLocal(temp); } Vector3f center = min.add(max).multLocal(0.5f); Vector3f extent = max.subtract(min).multLocal(0.5f); // Nehon 08/18/2010 : Added an offset to the extend to avoid banding artifacts when the frustum // are aligned return new BoundingBox(center, extent.x + 2.0f, extent.y + 2.0f, extent.z + 2.5f); }
/** * Rebuilds the cylinder based on a new set of parameters. * * @param axisSamples the number of samples along the axis. * @param radialSamples the number of samples around the radial. * @param radius the radius of the bottom of the cylinder. * @param radius2 the radius of the top of the cylinder. * @param height the cylinder's height. * @param closed should the cylinder have top and bottom surfaces. * @param inverted is the cylinder is meant to be viewed from the inside. */ public void updateGeometry( int axisSamples, int radialSamples, float radius, float radius2, float height, boolean closed, boolean inverted) { this.axisSamples = axisSamples + (closed ? 2 : 0); this.radialSamples = radialSamples; this.radius = radius; this.radius2 = radius2; this.height = height; this.closed = closed; this.inverted = inverted; // VertexBuffer pvb = getBuffer(Type.Position); // VertexBuffer nvb = getBuffer(Type.Normal); // VertexBuffer tvb = getBuffer(Type.TexCoord); // Vertices int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0); setBuffer(Type.Position, 3, createVector3Buffer(getFloatBuffer(Type.Position), vertCount)); // Normals setBuffer(Type.Normal, 3, createVector3Buffer(getFloatBuffer(Type.Normal), vertCount)); // Texture co-ordinates setBuffer(Type.TexCoord, 2, createVector2Buffer(vertCount)); int triCount = ((closed ? 2 : 0) + 2 * (axisSamples - 1)) * radialSamples; setBuffer(Type.Index, 3, createShortBuffer(getShortBuffer(Type.Index), 3 * triCount)); // generate geometry float inverseRadial = 1.0f / radialSamples; float inverseAxisLess = 1.0f / (closed ? axisSamples - 3 : axisSamples - 1); float inverseAxisLessTexture = 1.0f / (axisSamples - 1); float halfHeight = 0.5f * height; // Generate points on the unit circle to be used in computing the mesh // points on a cylinder slice. float[] sin = new float[radialSamples + 1]; float[] cos = new float[radialSamples + 1]; for (int radialCount = 0; radialCount < radialSamples; radialCount++) { float angle = FastMath.TWO_PI * inverseRadial * radialCount; cos[radialCount] = FastMath.cos(angle); sin[radialCount] = FastMath.sin(angle); } sin[radialSamples] = sin[0]; cos[radialSamples] = cos[0]; // calculate normals Vector3f[] vNormals = null; Vector3f vNormal = Vector3f.UNIT_Z; if ((height != 0.0f) && (radius != radius2)) { vNormals = new Vector3f[radialSamples]; Vector3f vHeight = Vector3f.UNIT_Z.mult(height); Vector3f vRadial = new Vector3f(); for (int radialCount = 0; radialCount < radialSamples; radialCount++) { vRadial.set(cos[radialCount], sin[radialCount], 0.0f); Vector3f vRadius = vRadial.mult(radius); Vector3f vRadius2 = vRadial.mult(radius2); Vector3f vMantle = vHeight.subtract(vRadius2.subtract(vRadius)); Vector3f vTangent = vRadial.cross(Vector3f.UNIT_Z); vNormals[radialCount] = vMantle.cross(vTangent).normalize(); } } FloatBuffer nb = getFloatBuffer(Type.Normal); FloatBuffer pb = getFloatBuffer(Type.Position); FloatBuffer tb = getFloatBuffer(Type.TexCoord); // generate the cylinder itself Vector3f tempNormal = new Vector3f(); for (int axisCount = 0, i = 0; axisCount < axisSamples; axisCount++, i++) { float axisFraction; float axisFractionTexture; int topBottom = 0; if (!closed) { axisFraction = axisCount * inverseAxisLess; // in [0,1] axisFractionTexture = axisFraction; } else { if (axisCount == 0) { topBottom = -1; // bottom axisFraction = 0; axisFractionTexture = inverseAxisLessTexture; } else if (axisCount == axisSamples - 1) { topBottom = 1; // top axisFraction = 1; axisFractionTexture = 1 - inverseAxisLessTexture; } else { axisFraction = (axisCount - 1) * inverseAxisLess; axisFractionTexture = axisCount * inverseAxisLessTexture; } } // compute center of slice float z = -halfHeight + height * axisFraction; Vector3f sliceCenter = new Vector3f(0, 0, z); // compute slice vertices with duplication at end point int save = i; for (int radialCount = 0; radialCount < radialSamples; radialCount++, i++) { float radialFraction = radialCount * inverseRadial; // in [0,1) tempNormal.set(cos[radialCount], sin[radialCount], 0.0f); if (vNormals != null) { vNormal = vNormals[radialCount]; } else if (radius == radius2) { vNormal = tempNormal; } if (topBottom == 0) { if (!inverted) nb.put(vNormal.x).put(vNormal.y).put(vNormal.z); else nb.put(-vNormal.x).put(-vNormal.y).put(-vNormal.z); } else { nb.put(0).put(0).put(topBottom * (inverted ? -1 : 1)); } tempNormal.multLocal((radius - radius2) * axisFraction + radius2).addLocal(sliceCenter); pb.put(tempNormal.x).put(tempNormal.y).put(tempNormal.z); tb.put((inverted ? 1 - radialFraction : radialFraction)).put(axisFractionTexture); } BufferUtils.copyInternalVector3(pb, save, i); BufferUtils.copyInternalVector3(nb, save, i); tb.put((inverted ? 0.0f : 1.0f)).put(axisFractionTexture); } if (closed) { pb.put(0).put(0).put(-halfHeight); // bottom center nb.put(0).put(0).put(-1 * (inverted ? -1 : 1)); tb.put(0.5f).put(0); pb.put(0).put(0).put(halfHeight); // top center nb.put(0).put(0).put(1 * (inverted ? -1 : 1)); tb.put(0.5f).put(1); } IndexBuffer ib = getIndexBuffer(); int index = 0; // Connectivity for (int axisCount = 0, axisStart = 0; axisCount < axisSamples - 1; axisCount++) { int i0 = axisStart; int i1 = i0 + 1; axisStart += radialSamples + 1; int i2 = axisStart; int i3 = i2 + 1; for (int i = 0; i < radialSamples; i++) { if (closed && axisCount == 0) { if (!inverted) { ib.put(index++, i0++); ib.put(index++, vertCount - 2); ib.put(index++, i1++); } else { ib.put(index++, i0++); ib.put(index++, i1++); ib.put(index++, vertCount - 2); } } else if (closed && axisCount == axisSamples - 2) { ib.put(index++, i2++); ib.put(index++, inverted ? vertCount - 1 : i3++); ib.put(index++, inverted ? i3++ : vertCount - 1); } else { ib.put(index++, i0++); ib.put(index++, inverted ? i2 : i1); ib.put(index++, inverted ? i1 : i2); ib.put(index++, i1++); ib.put(index++, inverted ? i2++ : i3++); ib.put(index++, inverted ? i3++ : i2++); } } } updateBound(); }
public Vector3f getDirectionToWaypoint() { Vector3f waypt = nextWaypoint.getPosition(); return waypt.subtract(currentPos3d).normalizeLocal(); }
private double basicCSG(Vector3f point, Skeleton currentSkeleton) { double sum = 0; boolean isCSG = SceneManager.get().csgEnabled; for (int i = 0; i < currentSkeleton.branches.size(); i++) { SkeletonBranch branch = currentSkeleton.branches.get(i); for (int j = 0; j < branch.points.size() - 1; j++) { SkeletonPoint SP1 = branch.points.get(j); SkeletonPoint SP2 = branch.points.get(j + 1); // TriangulationPoint P1 = SP1.point; // TriangulationPoint P2 = SP2.point; // Vector3f p = new Vector3f(P1.getXf(), P1.getYf(), P1.getZf()); // Vector3f q = new Vector3f(P2.getXf(), P2.getYf(), P2.getZf()); Vector3f p = SP1.point; Vector3f q = SP2.point; // calculate radius of influence float Rp = (float) SP1.radius; float Rq = (float) SP2.radius; // calculate surface points Sp and Sq Vector3f PQ = q.subtract(p); Vector3f normalVector = new Vector3f(-PQ.getY(), PQ.getX(), PQ.getZ()).normalize(); Vector3f Sp = p.add(normalVector.mult(Rp)); Vector3f Sq = q.add(normalVector.mult(Rq)); Vector3f Smid = Sp.add(Sq).divide(2f); // System.out.println("L: " + PQ.length() + " Sp: " + Sp + " Sq: " + // Sq + " Smid: " + Smid); // calculate weights double w0 = T / flt(Sp, p, q); double w1 = T / ft(Sq, p, q); // division factor w0 /= (double) SP1.divisionFactor; w1 /= (double) SP2.divisionFactor; double k = T / (w0 * flt(Smid, p, q) + w1 * ft(Smid, p, q)); // scale factor w0 *= k; w1 *= k; // System.out.println("j " + j); // System.out.println("w0 " + w0 + " w1 " + w1); // CSG blending if (isCSG) { double fx = cauchy(point, p, q, w0, w1); double R = cauchy(Smid, p, q, w0, w1); double blending = blending(-fx + T, R); sum += blending; } else { // common sum sum += cauchy(point, p, q, w0, w1); } } } // if(sum > 1) // blendingGTone++; // else if(sum < 1) // blendingLTone++; // sum /= n; // Vector3f A = new Vector3f(-5f, 0.0f, 0.0f); // Vector3f B = new Vector3f(5f, 0.0f, 0.0f); // Vector3f C = new Vector3f(-5f, 4.0f, 0.0f); // Vector3f D = new Vector3f(5f, 4.0f, 0.0f); // // // define threshold based on a pre determined surface point // float radius = 5.0f; // Vector3f AB = B.subtract(A); // Vector3f normalVectorAB = new Vector3f(-AB.getY(), AB.getX(), // AB.getZ()).normalize().mult(radius); // Vector3f midPointAB = (A.add(B)).divide(2f); // Vector3f surfacePointAB = midPointAB.add(normalVectorAB); // // T = 1.0; // // sum += blending(-cauchy(point, A, B) + T, cauchy(surfacePointAB, A, // B)); // sum += blending(-cauchy(point, C, D) + T, cauchy(surfacePointAB, C, // D)); // sum = cauchy(point, A, B) + cauchy(point, C, D); // if(!single) //i.e. is multiple // { // // common sum //// double result = -sum + T; //// if (result > 0) //// positive++; //// else if (result < 0) //// negative++; //// return result; // return sum; // } // else // { if (!isCSG) return T - sum; else // CSG composition return 1 - sum; // } }
// check if the area is greater than zero private static boolean isDegenerateTriangle(Vector3f a, Vector3f b, Vector3f c) { return (a.subtract(b).cross(c.subtract(b))).lengthSquared() == 0; }