/** * This method applies the variation to the particle with already set velocity. * * @param particle the particle to be affected */ protected void applyVelocityVariation(Particle particle) { particle.velocity.set(initialVelocity); temp.set(FastMath.nextRandomFloat(), FastMath.nextRandomFloat(), FastMath.nextRandomFloat()); temp.multLocal(2f); temp.subtractLocal(1f, 1f, 1f); temp.multLocal(initialVelocity.length()); particle.velocity.interpolate(temp, velocityVariation); }
@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; }
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(); } } }
@Override public void updateParticleData(ParticleData[] particles, Camera cam, Matrix3f inverseRotation) { for (int i = 0; i < particles.length; i++) { ParticleData p = particles[i]; int offset = templateVerts.capacity() * i; int colorOffset = templateColors.capacity() * i; if (p.life == 0 || !p.active) { for (int x = 0; x < templateVerts.capacity(); x += 3) { finVerts.put(offset + x, 0); finVerts.put(offset + x + 1, 0); finVerts.put(offset + x + 2, 0); } continue; } for (int x = 0; x < templateVerts.capacity(); x += 3) { switch (emitter.getBillboardMode()) { case Velocity: if (p.velocity.x != Vector3f.UNIT_Y.x && p.velocity.y != Vector3f.UNIT_Y.y && p.velocity.z != Vector3f.UNIT_Y.z) up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal(); else up.set(p.velocity).crossLocal(lock).normalizeLocal(); left.set(p.velocity).crossLocal(up).normalizeLocal(); dir.set(p.velocity); break; case Velocity_Z_Up: if (p.velocity.x != Vector3f.UNIT_Y.x && p.velocity.y != Vector3f.UNIT_Y.y && p.velocity.z != Vector3f.UNIT_Y.z) up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal(); else up.set(p.velocity).crossLocal(lock).normalizeLocal(); left.set(p.velocity).crossLocal(up).normalizeLocal(); dir.set(p.velocity); rotStore = tempQ.fromAngleAxis(-90 * FastMath.DEG_TO_RAD, left); left = rotStore.mult(left); up = rotStore.mult(up); break; case Velocity_Z_Up_Y_Left: up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal(); left.set(p.velocity).crossLocal(up).normalizeLocal(); dir.set(p.velocity); tempV3.set(left).crossLocal(up).normalizeLocal(); rotStore = tempQ.fromAngleAxis(90 * FastMath.DEG_TO_RAD, p.velocity); left = rotStore.mult(left); up = rotStore.mult(up); rotStore = tempQ.fromAngleAxis(-90 * FastMath.DEG_TO_RAD, left); up = rotStore.mult(up); break; case Normal: emitter.getShape().setNext(p.triangleIndex); tempV3.set(emitter.getShape().getNormal()); if (tempV3 == Vector3f.UNIT_Y) tempV3.set(p.velocity); up.set(tempV3).crossLocal(Vector3f.UNIT_Y).normalizeLocal(); left.set(tempV3).crossLocal(up).normalizeLocal(); dir.set(tempV3); break; case Normal_Y_Up: emitter.getShape().setNext(p.triangleIndex); tempV3.set(p.velocity); if (tempV3 == Vector3f.UNIT_Y) tempV3.set(Vector3f.UNIT_X); up.set(Vector3f.UNIT_Y); left.set(tempV3).crossLocal(up).normalizeLocal(); dir.set(tempV3); break; case Camera: up.set(cam.getUp()); left.set(cam.getLeft()); dir.set(cam.getDirection()); break; case UNIT_X: up.set(Vector3f.UNIT_Y); left.set(Vector3f.UNIT_Z); dir.set(Vector3f.UNIT_X); break; case UNIT_Y: up.set(Vector3f.UNIT_Z); left.set(Vector3f.UNIT_X); dir.set(Vector3f.UNIT_Y); break; case UNIT_Z: up.set(Vector3f.UNIT_X); left.set(Vector3f.UNIT_Y); dir.set(Vector3f.UNIT_Z); break; } tempV3.set(templateVerts.get(x), templateVerts.get(x + 1), templateVerts.get(x + 2)); tempV3 = rotStore.mult(tempV3); tempV3.multLocal(p.size); rotStore.fromAngles(p.angles.x, p.angles.y, p.angles.z); tempV3 = rotStore.mult(tempV3); tempV3.addLocal(p.position); if (!emitter.getParticlesFollowEmitter()) { tempV3.subtractLocal( emitter .getEmitterNode() .getWorldTranslation() .subtract(p.initialPosition)); // .divide(8f)); } finVerts.put(offset + x, tempV3.getX()); finVerts.put(offset + x + 1, tempV3.getY()); finVerts.put(offset + x + 2, tempV3.getZ()); } if (p.emitter.getApplyLightingTransform()) { for (int v = 0; v < templateNormals.capacity(); v += 3) { tempV3.set( templateNormals.get(v), templateNormals.get(v + 1), templateNormals.get(v + 2)); rotStore.fromAngles(p.angles.x, p.angles.y, p.angles.z); mat3.set(rotStore.toRotationMatrix()); float vx = tempV3.x, vy = tempV3.y, vz = tempV3.z; tempV3.x = mat3.get(0, 0) * vx + mat3.get(0, 1) * vy + mat3.get(0, 2) * vz; tempV3.y = mat3.get(1, 0) * vx + mat3.get(1, 1) * vy + mat3.get(1, 2) * vz; tempV3.z = mat3.get(2, 0) * vx + mat3.get(2, 1) * vy + mat3.get(2, 2) * vz; finNormals.put(offset + v, tempV3.getX()); finNormals.put(offset + v + 1, tempV3.getY()); finNormals.put(offset + v + 2, tempV3.getZ()); } } for (int v = 0; v < templateColors.capacity(); v += 4) { finColors .put(colorOffset + v, p.color.r) .put(colorOffset + v + 1, p.color.g) .put(colorOffset + v + 2, p.color.b) .put(colorOffset + v + 3, p.color.a * p.alpha); } } this.setBuffer(VertexBuffer.Type.Position, 3, finVerts); if (particles[0].emitter.getApplyLightingTransform()) this.setBuffer(VertexBuffer.Type.Normal, 3, finNormals); this.setBuffer(VertexBuffer.Type.Color, 4, finColors); updateBound(); }
private static BoneWorldGrid makeBoneWorldGrid( ByteArray3d boneMeshGrid, float worldScale, MyBone bone) { Transform transform = BoneTransformUtils.boneTransform2(bone); // bounding box needed for boneMeshGrid in world grid: float bs = 1.0f; Vector3f c1 = transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale); Vector3f c2 = transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale); Vector3f c3 = transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale); Vector3f c4 = transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale); Vector3f c5 = transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale); Vector3f c6 = transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale); Vector3f c7 = transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale); Vector3f c8 = transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale); Vector3f cmin = c1.clone(); cmin.minLocal(c2); cmin.minLocal(c3); cmin.minLocal(c4); cmin.minLocal(c5); cmin.minLocal(c6); cmin.minLocal(c7); cmin.minLocal(c8); Vector3f cmax = c1.clone(); cmax.maxLocal(c2); cmax.maxLocal(c3); cmax.maxLocal(c4); cmax.maxLocal(c5); cmax.maxLocal(c6); cmax.maxLocal(c7); cmax.maxLocal(c8); int xsize = (int) FastMath.ceil(cmax.x - cmin.x); int ysize = (int) FastMath.ceil(cmax.y - cmin.y); int zsize = (int) FastMath.ceil(cmax.z - cmin.z); ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize); int w = grid.getWidth(); int h = grid.getHeight(); int d = grid.getDepth(); Vector3f v = new Vector3f(); Vector3f inv = new Vector3f(); Vector3f inv2 = new Vector3f(); // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs))) // se let's precalculate it to (inv + shift) * scale Vector3f scale = new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth()) .divideLocal(bs * 2); Vector3f shift = Vector3f.UNIT_XYZ.mult(bs); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner // loop // can be calculated by adding (inv2-inv1) because the transforms are linear v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv); inv.addLocal(shift).multLocal(scale); v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv2); inv2.addLocal(shift).multLocal(scale); Vector3f add = inv2.subtractLocal(inv); for (int z = 0; z < d; z++) { inv.addLocal(add); if (inv.x >= 0 && inv.x < boneMeshGrid.getWidth() && inv.y >= 0 && inv.y < boneMeshGrid.getHeight() && inv.z >= 0 && inv.z < boneMeshGrid.getDepth()) { grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z)); } } } } // Once the boneMeshGrid has been transformed into world grid, it may suffer from // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor). // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that // the shape blends better with other bones' shapes. blurGrid(grid); BoneWorldGrid bwg2 = new BoneWorldGrid(); bwg2.grid = grid; bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z)); return bwg2; }