/** * This is an external all for direct usage. * * @param tpf */ public void pick(Vector3f direction) { results.clear(); this.direction = direction; ray.setOrigin(originObject.getWorldTranslation()); ray.setDirection(direction); scene.collideWith(ray, results); if (results.size() > 0) { // The closest collision point is what was truly hit: for (int i = 0; i < results.size(); i++) { CollisionResult col = results.getCollision(i); if (collisionTypes != null && !originObject.hasChild(col.getGeometry())) { for (int j = 0; j < collisionTypes.length; j++) { String typeStr = collisionTypes[j]; String type = col.getGeometry().getUserData(TYPE); if (type != null && type.equals(typeStr)) { contactPoint = col.getContactPoint(); contactObject = col.getGeometry(); fireSpatialListener(contactPoint, contactObject, true); } } } } } }
public void onAction(String name, boolean keyPressed, float tpf) { if (name.equals("KEY_R") && !keyPressed) {} if (name.equals("KEY_F10") && !keyPressed) { showMainMenu(); } if (name.equals("LMB") && !keyPressed) { CollisionResults results = new CollisionResults(); Vector2f click2d = app.getInputManager().getCursorPosition(); Vector3f click3d = app.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone(); Vector3f dir = app.getCamera() .getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f) .subtractLocal(click3d); Ray ray = new Ray(click3d, dir); /* Collect intersections between Ray and nodes in results list */ resourceNodes.collideWith(ray, results); farmNodes.collideWith(ray, results); locationNodes.collideWith(ray, results); if (results.size() > 0) { CollisionResult closest = results.getClosestCollision(); Geometry geom = closest.getGeometry(); String geomName = geom.getName(); if (geom.getUserData(geomName) instanceof Farm) { Farm farm = (Farm) geom.getUserData(geomName); setMessageHUD("Clicked on Farm cost: " + farm.getCost()); } if (geom.getUserData(geomName) instanceof Location) { Location loc = (Location) geom.getUserData(geomName); setMessageHUD("Clicked on Location: " + loc.getName()); } if (geom.getUserData(geomName) instanceof Resource) { Resource res = (Resource) geom.getUserData(geomName); Integer cost = null; if (res.getType() == Resource.CHICK) { cost = gm.getResourceManager().getCurrentPriceChicken(); } else if (res.getType() == Resource.LAMB) { cost = gm.getResourceManager().getCurrentPriceLamb(); } else if (res.getType() == Resource.PIGLET) { cost = gm.getResourceManager().getCurrentPricePiglet(); } else if (res.getType() == Resource.CALF) { cost = gm.getResourceManager().getCurrentPriceCalf(); } setMessageHUD("Clicked on " + res.getName() + " cost: " + cost); } } } }
private static CollisionResult getCollision(Node n, Ray r) { CollisionResults results = new CollisionResults(); n.collideWith(r, results); if (results.size() == 0) { return null; } return results.getClosestCollision(); }
public int collideWith(Collidable other) { TempVars tempVars = TempVars.get(); try { CollisionResults tempResults = tempVars.collisionResults; tempResults.clear(); return collideWith(other, tempResults); } finally { tempVars.release(); } }
public void onAction(String name, boolean keyPressed, float tpf) { if (name.equals("Shoot") && !keyPressed) { // 1. Reset results list. CollisionResults results = new CollisionResults(); // 2. Aim the ray from cam loc to cam direction. Ray ray = new Ray(cam.getLocation(), cam.getDirection()); // 3. Collect intersections between Ray and Shootables in results list. shootables.collideWith(ray, results); // 4. Print the results System.out.println("----- Collisions? " + results.size() + "-----"); for (int i = 0; i < results.size(); i++) { // For each hit, we know distance, impact point, name of geometry. float dist = results.getCollision(i).getDistance(); Vector3f pt = results.getCollision(i).getContactPoint(); String hit = results.getCollision(i).getGeometry().getName(); System.out.println("* Collision #" + i); System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); } // 5. Use the results (we mark the hit object) if (results.size() > 0) { // The closest collision point is what was truly hit: CollisionResult closest = results.getClosestCollision(); // Let's interact - we mark the hit with a red dot. mark.setLocalTranslation(closest.getContactPoint()); rootNode.attachChild(mark); } else { // No hits? Then remove the red mark. rootNode.detachChild(mark); } } }
@Override public void update(float tpf) { super.update(tpf); // If the mouse is being dragged, update the locations of any dragged // temporary geometries. To determine if the locations need to be // updated, the mouse button must be down AND the mouse must have moved // since the last update. if (!click.get() && newTemporaryPosition.getAndSet(false)) { // Add the temporary spatials node if the drag has just started. if (!showTemporarySpatials.getAndSet(true)) { appState.getRootNode().attachChild(tempSpatials); } // Get the cursor's current location on the grid. CollisionResults results = getCollision(grid, appState.getCursorRay()); if (results.size() > 0) { // Determine the vector between the start point for the mouse // drag and the current location of the mouse drag. Vector3f dragLoc = appState.getClosestGridPoint(results.getClosestCollision().getContactPoint()); dragLoc.subtractLocal(dragStart); // We need to modify the controllers for all the // currently-selected vertices. It's possible that // selectionChanged() is executing at the same time, so we need // to temporarily "lock" the selected vertex data structures. selectionLock.lock(); try { // Add the vector to all temporary vertices. for (Entry<Integer, Vertex> e : selectedVertices.entrySet()) { float[] array = e.getValue().getLocation(); Vector3f location = dragLoc.add(array[0], array[1], array[2]); vertexControllers.get(e.getKey()).setLocation(location); } } finally { selectionLock.unlock(); } } } // If the dragging has stopped and we are still showing temporary // spatials in the scene, stop showing them. else if (!drag.get() && showTemporarySpatials.getAndSet(false)) { appState.getRootNode().detachChild(tempSpatials); } return; }
private Vector3f getWorldIntersection() { Vector3f origin = cam.getWorldCoordinates( new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); Vector3f direction = cam.getWorldCoordinates( new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); direction.subtractLocal(origin).normalizeLocal(); Ray ray = new Ray(origin, direction); CollisionResults results = new CollisionResults(); int numCollisions = terrain.collideWith(ray, results); if (numCollisions > 0) { CollisionResult hit = results.getClosestCollision(); return hit.getContactPoint(); } return null; }
/** * Prints out a CollisionResults Collection for debugging/diagnosis. * * @param results A CollisionResults Collection to print out. */ public void printCollisionResults(CollisionResults results) { if (results != null) { // Print the results of the collision. logger.info("Hits: " + results.size()); if (results.size() > 0) { // Print the results. for (CollisionResult result : results) { // For each hit, we know distance, impact point, name of // geometry. float dist = result.getDistance(); Vector3f pt = result.getContactPoint(); String hit = result.getGeometry().getName(); logger.info("Hit " + hit + " at distance " + dist + " at location " + pt.toString()); } } } return; }
public static void HighlightModel(Camera cam, InputManager inputManager) { CollisionResults results = new CollisionResults(); Vector2f mouseCoords = new Vector2f(inputManager.getCursorPosition()); Ray mouseRay = new Ray( cam.getWorldCoordinates(mouseCoords, 0), cam.getWorldCoordinates(mouseCoords, 1) .subtractLocal(cam.getWorldCoordinates(mouseCoords, 0)) .normalizeLocal()); Main.s_TreeNode.collideWith(mouseRay, results); if (results.size() > 0) { Spatial target = results.getClosestCollision().getGeometry(); AmbientLight light = new AmbientLight(); light.setColor(ColorRGBA.Blue); Main.s_TreeNode.addLight(light); target.addLight(light); } }
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 doPicking() { Point mouse = canvas.getMousePosition(); if (mouse == null) { clearLabel(); } else { vec2.x = mouse.x; vec2.y = canvas.getHeight() - mouse.y; // create ray Vector3f end = scene.getCamera().getWorldCoordinates(vec2, 0.2f); Vector3f start = scene.getCamera().getLocation(); Ray ray = new Ray(start, end.subtractLocal(start).normalizeLocal()); // do collision checking CollisionResults results = new CollisionResults(); scene.getRootNode().collideWith(ray, results); CollisionResult result = results.getClosestCollision(); if (result != null) { Vector3f contactPoint = result.getContactPoint(); setLabel(contactPoint); } else { clearLabel(); } } }
public static void MoveModel(Camera cam, InputManager inputManager, Spatial scene) { if (Statics.s_PlayerSettingModel == true) { CollisionResults results = new CollisionResults(); Ray ray = new Ray(); Vector2f click2d = inputManager.getCursorPosition(); Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.getX(), click2d.getY()), 0f); Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.getX(), click2d.getY()), 1f) .subtractLocal(click3d) .normalizeLocal(); ray.setOrigin(click3d); ray.setDirection(dir); ray = new Ray(click3d, dir); scene.collideWith(ray, results); if (results.size() > 0) { CollisionResult point = results.getClosestCollision(); Vector3f destination = point.getContactPoint(); ObjectHelper.s_Model.setMaterial(ObjectHelper.greenTrans); SetModel(destination); } } }
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 final int intersectBrute( Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) { float tHit = Float.POSITIVE_INFINITY; TempVars vars = TempVars.get(); Vector3f v1 = vars.vect1, v2 = vars.vect2, v3 = vars.vect3; int cols = 0; ArrayList<BIHStackData> stack = vars.bihStack; stack.clear(); // stack.add(new BIHStackData(this, 0, 0)); vars.addStackData(this, 0f, 0f); stackloop: while (stack.size() > 0) { BIHStackData data = stack.remove(stack.size() - 1); BIHNode node = data.node; leafloop: while (node.axis != 3) { // while node is not a leaf BIHNode nearNode, farNode; nearNode = node.left; farNode = node.right; // stack.add(new BIHStackData(farNode, 0, 0)); vars.addStackData(farNode, 0f, 0f); node = nearNode; } // a leaf for (int i = node.leftIndex; i <= node.rightIndex; i++) { tree.getTriangle(i, v1, v2, v3); if (worldMatrix != null) { worldMatrix.mult(v1, v1); worldMatrix.mult(v2, v2); worldMatrix.mult(v3, v3); } float t = r.intersects(v1, v2, v3); if (t < tHit) { tHit = t; vars.vect4.set(r.direction).multLocal(tHit).addLocal(r.origin); CollisionResult cr = results.addReusedCollision(vars.vect4.x, vars.vect4.y, vars.vect4.z, tHit); cr.setTriangleIndex(tree.getTriangleIndex(i)); results.addCollision(cr); cols++; } } } vars.release(); return cols; }
/* * (non-Javadoc) * * @see * org.eclipse.ice.client.widgets.mesh.MeshAppStateMode#leftClick(boolean , * float) */ @Override public void leftClick(boolean isPressed, float tpf) { super.leftClick(isPressed, tpf); // Update the mouseDown boolean. mouseDown.set(isPressed); // We need to differentiate between mouse clicks and mouse drags. Below, // we classify them as follows: // If your mouse down+up is less than 0.25 seconds, it's a click. // If your mouse down+up is greater than 0.25 seconds, then: // if the mouse did not move, it is a click // if the mouse moved, it is a drag if (mouseDown.get()) { // Start a timer for the click. The click timer should expire after // a quarter of a second. Then it should set the boolean "click" to // false. clickTimer = new Timer(true); clickTimer.schedule( new TimerTask() { @Override public void run() { click.set(false); } }, clickThreshold); // Set the starting location of the mouse drag. CollisionResults results = getCollision(grid, appState.getCursorRayFromClick()); if (results.size() > 0) { dragStart = appState.getClosestGridPoint(results.getClosestCollision().getContactPoint()); } } // Note: We have to check the clickTimer because it may be possible for // the AWTPanel to fire a mouse release event but not a mouse press // event. else if (clickTimer != null) { // Stop the click timer. clickTimer.cancel(); // We need to get the current state of the click and drag booleans. // We should also reset them since the mouseUp signals the end of // the sequence of mouse events. boolean click = this.click.getAndSet(true); boolean drag = this.drag.getAndSet(false); // The first condition is for clicks. Either the click was fast // enough or the mouse did not move. if (click || !drag) { // Determine whether or not shift and control were pressed. boolean addToSelection = shiftPressed.get(); boolean toggleSelection = controlPressed.get(); // Get the Vertex for the clicked geometry if possible and add // it to the collection of selected vertices. CollisionResults results = getCollision(vertexSpatials, appState.getCursorRayFromClick()); Vertex clickedVertex = null; int id = 0; if (results.size() > 0) { // Get the Vertex ID from the VertexView. id = Integer.parseInt(results.getClosestCollision().getGeometry().getName()); clickedVertex = appState.getMesh().getVertex(id); } MeshSelectionManager selection = appState.getSelectionManager(); if (addToSelection) { // A shift-click should only add the clicked item to the // current selection. if (clickedVertex != null) { selection.selectVertex(id); } } else if (toggleSelection) { // A control-click should toggle clicked item's selection // state. if (clickedVertex != null) { if (selection.getSelectedVertexIds().contains(id)) { selection.deselectVertex(id); } else { selection.selectVertex(id); } } } else { // A standard click should clear the selection and set the // clicked item (if any) to the current selection. selection.clearSelection(); if (clickedVertex != null) { selection.selectVertex(id); } } } // The second condition is for drags. The click was too slow and the // mouse moved. else { // For now, all drag does it drag the currently-selected // vertices. We do not draw boxes around things yet, so we do // not need to check for shift or control. // Update the location for each of the selected vertices. for (Vertex v : selectedVertices.values()) { VertexController controller = vertexControllers.get(v.getId()); Vector3f location = controller.getLocation(); v.setLocation(location.x, location.y, location.z); } } // Reset the click timer. clickTimer = null; } return; }
public final int intersectWhere( Collidable col, BoundingBox box, Matrix4f worldMatrix, BIHTree tree, CollisionResults results) { TempVars vars = TempVars.get(); ArrayList<BIHStackData> stack = vars.bihStack; stack.clear(); float[] minExts = { box.getCenter().x - box.getXExtent(), box.getCenter().y - box.getYExtent(), box.getCenter().z - box.getZExtent() }; float[] maxExts = { box.getCenter().x + box.getXExtent(), box.getCenter().y + box.getYExtent(), box.getCenter().z + box.getZExtent() }; // stack.add(new BIHStackData(this, 0, 0)); vars.addStackData(this, 0f, 0f); Triangle t = new Triangle(); int cols = 0; stackloop: while (stack.size() > 0) { BIHNode node = stack.remove(stack.size() - 1).node; while (node.axis != 3) { int a = node.axis; float maxExt = maxExts[a]; float minExt = minExts[a]; if (node.leftPlane < node.rightPlane) { // means there's a gap in the middle // if the box is in that gap, we stop there if (minExt > node.leftPlane && maxExt < node.rightPlane) { continue stackloop; } } if (maxExt < node.rightPlane) { node = node.left; } else if (minExt > node.leftPlane) { node = node.right; } else { // stack.add(new BIHStackData(node.right, 0, 0)); vars.addStackData(node.right, 0f, 0f); node = node.left; } // if (maxExt < node.leftPlane // && maxExt < node.rightPlane){ // node = node.left; // }else if (minExt > node.leftPlane // && minExt > node.rightPlane){ // node = node.right; // }else{ // } } for (int i = node.leftIndex; i <= node.rightIndex; i++) { tree.getTriangle(i, t.get1(), t.get2(), t.get3()); if (worldMatrix != null) { worldMatrix.mult(t.get1(), t.get1()); worldMatrix.mult(t.get2(), t.get2()); worldMatrix.mult(t.get3(), t.get3()); } int added = col.collideWith(t, results); if (added > 0) { int index = tree.getTriangleIndex(i); int start = results.size() - added; for (int j = start; j < results.size(); j++) { CollisionResult cr = results.getCollisionDirect(j); cr.setTriangleIndex(index); } cols += added; } } } vars.release(); return cols; }
public Material getMaterial() { CollisionResults rMaterial = new CollisionResults(); getSpatial().collideWith(getSpatial().getWorldBound(), rMaterial); rMaterial.toString(); return rMaterial.getClosestCollision().getGeometry().getMaterial(); }