@Override public void getRandomPoint(Vector3f store) { do { store.x = (FastMath.nextRandomFloat() * 2f - 1f) * radius; store.y = (FastMath.nextRandomFloat() * 2f - 1f) * radius; store.z = (FastMath.nextRandomFloat() * 2f - 1f) * radius; } while (store.distance(center) > radius); }
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 MouseStatus getMouseCollision() { if (gui.isMouseOver()) { return null; } Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f); Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f); direction.subtractLocal(origin).normalizeLocal(); Ray ray = new Ray(origin, direction); CollisionResults results = new CollisionResults(); clickableNode.collideWith(ray, results); Vector3f v3f = null; Model m = null; if (results.size() > 0) { CollisionResult closest = results.getClosestCollision(); Geometry g = closest.getGeometry(); v3f = closest.getContactPoint(); m = Model.Geometry2Model(g); // return new // MouseStatus(m,closest.getContactPoint().getX(),closest.getContactPoint().getZ()); } if (water != null) { Vector3f waterv = water.collision(ray); if (waterv != null && (v3f == null || waterv.distance(origin) < v3f.distance(origin))) { v3f = waterv; } } if (v3f != null) return new MouseStatus(m, v3f.getX(), v3f.getZ()); return null; }
private void computeLength() { int M = 16; Vector3f old = null; float length = 0; for (int i = 0; i <= M; ++i) { Vector3f v = interpolate(i / (float) M).position; if (old != null) { length += old.distance(v); } old = v; } stepLength = length; }
public boolean calculateLod( TerrainPatch patch, List<Vector3f> locations, HashMap<String, UpdatedTerrainPatch> updates) { if (turnOffLod) { // set to full detail int prevLOD = patch.getLod(); UpdatedTerrainPatch utp = updates.get(patch.getName()); if (utp == null) { utp = new UpdatedTerrainPatch(patch); updates.put(utp.getName(), utp); } utp.setNewLod(0); utp.setPreviousLod(prevLOD); // utp.setReIndexNeeded(true); return true; } float[] lodEntropies = patch.getLodEntropies(); float cameraConstant = getCameraConstant(cam, pixelError); Vector3f patchPos = getCenterLocation(patch); // vector from camera to patch // Vector3f toPatchDir = locations.get(0).subtract(patchPos).normalizeLocal(); // float facing = cam.getDirection().dot(toPatchDir); float distance = patchPos.distance(locations.get(0)); // go through each lod level to find the one we are in for (int i = 0; i <= patch.getMaxLod(); i++) { if (distance < lodEntropies[i] * cameraConstant || i == patch.getMaxLod()) { boolean reIndexNeeded = false; if (i != patch.getLod()) { reIndexNeeded = true; // System.out.println("lod change: "+lod+" > "+i+" dist: // "+distance); } int prevLOD = patch.getLod(); UpdatedTerrainPatch utp = updates.get(patch.getName()); if (utp == null) { utp = new UpdatedTerrainPatch(patch); // save in here, do not update actual variables updates.put(utp.getName(), utp); } utp.setNewLod(i); utp.setPreviousLod(prevLOD); // utp.setReIndexNeeded(reIndexNeeded); return reIndexNeeded; } } return false; }
private boolean maxDistanceExceeded(Vector3f vehiclePos) { // get box's position on xz-plane (ignore y component) Vector3f followBoxPosition = getPosition(); followBoxPosition.setY(0); // get vehicle's position on xz-plane (ignore y component) Vector3f vehiclePosition = vehiclePos; vehiclePosition.setY(0); // distance between box and vehicle float currentDistance = followBoxPosition.distance(vehiclePosition); // report whether maximum distance is exceeded return currentDistance > maxDistance; }
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 Hallway(Vector3f start, float xi, float zi) { float x = start.getX() + xi; float z = start.getZ() + zi; float rng, dist; int len = 0; int spread = 0; int lenMax = FastMath.nextRandomInt(HALL_LENGTH_MIN, HALL_LENGTH_MAX); boolean b = false; // Make sure both xi and zi have an absolute value of 1: xi = A.sign(xi); zi = A.sign(zi); // Assign the first 2 corners: corners[0] = new Vector3f( (zi * (HALL_WIDTH - 1)) + x, start.getY(), (xi * (HALL_WIDTH - 1)) + z); // Bottom Left corners[1] = new Vector3f( (-zi * (HALL_WIDTH - 1)) + x, start.getY(), (-xi * (HALL_WIDTH - 1)) + z); // Bottom Right Vector3f left = corners[0].clone(); Vector3f right = corners[1].clone(); ArrayList<HallData> newHalls = new ArrayList(1); while (len <= lenMax) { if (world.get(left) != null && world.get(left).contains("h")) { b = true; } if (world.get(right) != null && world.get(right).contains("h")) { b = true; } // Check each of the spaces in this step for hallway: if (b) { right.addLocal(-xi, 0, -zi); left.addLocal(-xi, 0, -zi); break; } world.put(left.clone(), "h"); world.put(right.add(zi, 0, xi), "h"); world.put(right.clone(), "h"); // Check distance & random to see if more hallways should be created: dist = left.distance(Vector3f.ZERO); rng = FastMath.nextRandomFloat(); if (dist < HALL_MAX_RADIUS && spread > HALL_SPREAD && len < lenMax) { if (rng < 0.13f) { newHalls.add(new HallData(left.clone(), zi, xi)); spread = 0; } else if (rng < 0.26f) { newHalls.add(new HallData(right.clone(), -zi, -xi)); spread = 0; } else if (rng < 0.33f) { newHalls.add(new HallData(left.clone(), zi, xi)); newHalls.add(new HallData(right.clone(), -zi, -xi)); spread = 0; } } x += xi; z += zi; spread++; len++; left.addLocal(xi, 0, zi); right.addLocal(xi, 0, zi); } corners[2] = right.clone(); // Top Right corners[3] = left.clone(); // Top Left // Generate hallways: int j = 0; while (j < newHalls.size()) { hallways.add(new Hallway(newHalls.get(j).start, newHalls.get(j).xi, newHalls.get(j).zi)); j++; } // Return if there's no hallway to generate (0 in size): float xs = FastMath.abs(corners[1].getX() - corners[3].getX()) + 1; float zs = FastMath.abs(corners[1].getZ() - corners[3].getZ()) + 1; if (Math.min(FastMath.abs(xs), FastMath.abs(zs)) < 1) { return; } // Generate the front wall: walls.add(new Wall(left.add(xi, 0, zi), -zi, -xi, HALL_WIDTH * 2 - 1)); walls.add(new Wall(left.add(zi, 0, xi), -xi, -zi, len + 1)); walls.add(new Wall(right.add(-zi, 0, -xi), -xi, -zi, len + 1)); // Generate the actual floor: float xloc = (corners[3].getX() + corners[1].getX()) * 0.5f; float zloc = (corners[3].getZ() + corners[1].getZ()) * 0.5f; NPCManager.addNew("grunt", new Vector3f(xloc, start.getY(), zloc).mult(ZS).add(0, 5, 0)); center = new Vector3f(xloc, start.getY() - 0.5f, zloc); floor = geoFloor(center, xs, zs, T.getMaterialPath("BC_Tex"), new Vector2f(zs, xs), true); map.add(floor); }
public final int intersectWhere( Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) { TempVars vars = TempVars.get(); ArrayList<BIHStackData> stack = vars.bihStack; stack.clear(); // float tHit = Float.POSITIVE_INFINITY; Vector3f o = vars.vect1.set(r.getOrigin()); Vector3f d = vars.vect2.set(r.getDirection()); Matrix4f inv = vars.tempMat4.set(worldMatrix).invertLocal(); inv.mult(r.getOrigin(), r.getOrigin()); // Fixes rotation collision bug inv.multNormal(r.getDirection(), r.getDirection()); // inv.multNormalAcross(r.getDirection(), r.getDirection()); // this is a no-no: allocating float arrays for immediate use? blarny! /*float[] origins = {r.getOrigin().x, r.getOrigin().y, r.getOrigin().z}; float[] invDirections = {1f / r.getDirection().x, 1f / r.getDirection().y, 1f / r.getDirection().z};*/ r.getDirection().normalizeLocal(); Vector3f v1 = vars.vect3, v2 = vars.vect4, v3 = vars.vect5; int cols = 0; // stack.add(new BIHStackData(this, sceneMin, sceneMax)); vars.addStackData(this, sceneMin, sceneMax); stackloop: while (stack.size() > 0) { BIHStackData data = stack.remove(stack.size() - 1); BIHNode node = data.node; float tMin = data.min, tMax = data.max; if (tMax < tMin) { continue; } leafloop: while (node.axis != 3) { // while node is not a leaf int a = node.axis; // find the origin and direction value for the given axis float origin, invDirection; switch (a) { default: case 0: // x origin = r.getOrigin().x; invDirection = 1f / r.getDirection().x; break; case 1: // y origin = r.getOrigin().y; invDirection = 1f / r.getDirection().y; break; case 2: // z origin = r.getOrigin().z; invDirection = 1f / r.getDirection().z; break; } // float origin = origins[a]; // float invDirection = invDirections[a]; float tNearSplit, tFarSplit; BIHNode nearNode, farNode; tNearSplit = (node.leftPlane - origin) * invDirection; tFarSplit = (node.rightPlane - origin) * invDirection; nearNode = node.left; farNode = node.right; if (invDirection < 0) { float tmpSplit = tNearSplit; tNearSplit = tFarSplit; tFarSplit = tmpSplit; BIHNode tmpNode = nearNode; nearNode = farNode; farNode = tmpNode; } if (tMin > tNearSplit && tMax < tFarSplit) { continue stackloop; } if (tMin > tNearSplit) { tMin = max(tMin, tFarSplit); node = farNode; } else if (tMax < tFarSplit) { tMax = min(tMax, tNearSplit); node = nearNode; } else { // stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax)); vars.addStackData(farNode, max(tMin, tFarSplit), tMax); tMax = min(tMax, tNearSplit); node = nearNode; } } // if ( (node.rightIndex - node.leftIndex) > minTrisPerNode){ // // on demand subdivision // node.subdivide(); // stack.add(new BIHStackData(node, tMin, tMax)); // continue stackloop; // } // a leaf for (int i = node.leftIndex; i <= node.rightIndex; i++) { tree.getTriangle(i, v1, v2, v3); float t = r.intersects(v1, v2, v3); if (!Float.isInfinite(t)) { if (worldMatrix != null) { worldMatrix.mult(v1, v1); worldMatrix.mult(v2, v2); worldMatrix.mult(v3, v3); vars.ray.setOrigin(o); vars.ray.setDirection(d); float t_world = vars.ray.intersects(v1, v2, v3); t = t_world; } Vector3f contactPoint = vars.vect4.set(d).multLocal(t).addLocal(o); float worldSpaceDist = o.distance(contactPoint); // don't add the collision if it is longer than the ray length if (worldSpaceDist <= r.limit) { CollisionResult cr = results.addReusedCollision( contactPoint.x, contactPoint.y, contactPoint.z, worldSpaceDist); if (cr.getContactNormal() == null) { cr.setContactNormal(Triangle.computeTriangleNormal(v1, v2, v3, null)); } else { Triangle.computeTriangleNormal(v1, v2, v3, cr.getContactNormal()); } cr.setTriangleIndex(tree.getTriangleIndex(i)); cols++; } } } } vars.release(); r.setOrigin(o); r.setDirection(d); return cols; }
public float getReducedSpeed() { // return a temporarily reduced speed for the traffic car // in order to reach next (lower) speed limit in time float reducedSpeedInKmh = Float.POSITIVE_INFINITY; // if next way point with lower speed comes closer --> reduce speed int currentIndex = motionControl.getCurrentWayPoint(); Waypoint nextWP = getNextWayPoint(currentIndex); if (nextWP != null) { // current way point (already passed) Waypoint curentWP = waypointList.get(currentIndex); // speed at current way point float currentSpeedInKmh = curentWP.getSpeed(); float currentSpeed = currentSpeedInKmh / 3.6f; // speed at next way point float targetSpeedInKmh = nextWP.getSpeed(); float targetSpeed = targetSpeedInKmh / 3.6f; // if speed at the next WP is lower than at the current WP --> brake vehicle if (targetSpeed < currentSpeed) { // % of traveled distance between current and next way point float wayPercentage = motionControl.getCurrentValue(); // distance between current and next way point Vector3f currentPos = curentWP.getPosition().clone(); currentPos.setY(0); Vector3f nextPos = nextWP.getPosition().clone(); nextPos.setY(0); float distance = currentPos.distance(nextPos); // distance (in meters) between follow box and next way point float distanceToNextWP = (1 - wayPercentage) * distance; // speed difference in m/s between current WP's speed and next WP's speed float speedDifference = currentSpeed - targetSpeed; // compute the distance in front of the next WP at what the vehicle has to start // braking with 50% brake force in order to reach the next WP's (lower) speed in time. float deceleration50Percent = 50f * vehicle.getMaxBrakeForce() / vehicle.getMass(); // time in seconds needed for braking process float time = speedDifference / deceleration50Percent; // distance covered during braking process float coveredDistance = 0.5f * -deceleration50Percent * time * time + currentSpeed * time; // start braking in x meters float distanceToBrakingPoint = distanceToNextWP - coveredDistance; if (distanceToBrakingPoint < 0) { // reduce speed linearly beginning from braking point // % of traveled distance between braking point and next way point float speedPercentage = -distanceToBrakingPoint / coveredDistance; // 0% traveled: reduced speed = currentSpeed // 50% traveled: reduced speed = (currentSpeed+targetSpeed)/2 // 100% traveled: reduced speed = targetSpeed float reducedSpeed = currentSpeed - (speedPercentage * speedDifference); reducedSpeedInKmh = reducedSpeed * 3.6f; /* if(vehicle.getName().equals("car1")) { float vehicleSpeedInKmh = vehicle.getLinearSpeedInKmh(); System.out.println(curentWP.getName() + " : " + speedPercentage + " : " + reducedSpeedInKmh + " : " + vehicleSpeedInKmh + " : " + targetSpeedInKmh); } */ } } } return reducedSpeedInKmh; }
public float getDistanceToWaypoint() { return currentPos3d.distance(nextWaypoint.getPosition()); }
/** * Find the distance from the center of this Bounding Volume to the given point. * * @param point The point to get the distance to * @return distance */ public final float distanceTo(Vector3f point) { return center.distance(point); }