List of usage examples for org.apache.commons.math3.geometry.euclidean.threed Vector3D getX
public double getX()
From source file:org.jtrfp.trcl.obj.DEFObject.java
private void fallingObjectBehavior() { canTurn = false;/*from w w w . jav a 2 s.c o m*/ mobile = false;//Technically wrong but propulsion is unneeded. //addBehavior(new PulledDownByGravityBehavior()); final MovesByVelocity mbv = new MovesByVelocity(); mbv.setVelocity(new Vector3D(3500, -100000, 5000)); addBehavior(mbv); //addBehavior(new VelocityDragBehavior().setDragCoefficient(.99)); // For some reason it falls like pine tar addBehavior(new DamageableBehavior().setMaxHealth(10).setHealth(10)); addBehavior(new DeathBehavior()); addBehavior(new CollidesWithTerrain().setIgnoreCeiling(true)); addBehavior(new DamagedByCollisionWithSurface()); addBehavior(new RotationalMomentumBehavior().setEquatorialMomentum(.01).setLateralMomentum(.02) .setPolarMomentum(.03)); { final DEFObject thisObject = this; final TR thisTr = getTr(); addBehavior(new ResetsRandomlyAfterDeath().setMinWaitMillis(1000).setMaxWaitMillis(5000) .setRunOnReset(new Runnable() { @Override public void run() { final Vector3D centerPos = thisObject.probeForBehavior(DeathBehavior.class) .getLocationOfLastDeath(); thisObject.probeForBehavior(MovesByVelocity.class) .setVelocity(new Vector3D(7000, -200000, 1000)); final double[] pos = thisObject.getPosition(); pos[0] = centerPos.getX() + Math.random() * TR.mapSquareSize * 3 - TR.mapSquareSize * 1.5; pos[1] = thisTr.getWorld().sizeY / 2 + thisTr.getWorld().sizeY * (Math.random()) * .3; pos[2] = centerPos.getZ() + Math.random() * TR.mapSquareSize * 3 - TR.mapSquareSize * 1.5; thisObject.notifyPositionChange(); }//end run() })); } }
From source file:org.jtrfp.trcl.obj.Explosion.java
public Explosion(TR tr, ExplosionType type) { super(tr, type.getMillisPerFrame(), type.getAnimationFiles().length); final Vector3D origin = type.getOrigin(); this.setModelOffset(origin.getX() * type.getBillboardSize().getWidth() * -.5, origin.getY() * type.getBillboardSize().getHeight() * -.5, origin.getZ()); this.type = type; setBillboardSize(type.getBillboardSize()); if (type.isRandomRotate()) setRotation(2 * Math.PI * Math.random()); String[] aniFiles = type.getAnimationFiles(); Texture[] frames = new Texture[aniFiles.length]; try {//www . j a va 2s . c o m for (int i = 0; i < aniFiles.length; i++) { frames[i] = frame(aniFiles[i]); } } //end try{} catch (Exception e) { e.printStackTrace(); } setTexture(new AnimatedTexture(getSequencer(), frames), true); }
From source file:org.jtrfp.trcl.obj.ExplosionSystem.java
public Explosion triggerExplosion(Vector3D loc, ExplosionType type) { if (!isNewExplosionFeasible(loc, type)) return null; indices[type.ordinal()]++;/* www . ja v a 2s . co m*/ indices[type.ordinal()] %= MAX_EXPLOSIONS_PER_POOL; Explosion result = allExplosions[type.ordinal()][indices[type.ordinal()]]; result.destroy(); result.reset(); result.setPosition(loc.getX(), loc.getY(), loc.getZ()); result.notifyPositionChange(); final SmokeSystem sf = tr.getResourceManager().getSmokeSystem(); final int NUM_PUFFS = 1; for (int i = 0; i < NUM_PUFFS; i++) { sf.triggerSmoke(loc.add(new Vector3D(Math.random() * 10000 - 5000, Math.random() * 10000 - 5000, Math.random() * 10000 - 5000)), SmokeType.Puff); } //end for(i) add(result); return result; }
From source file:org.jtrfp.trcl.obj.TunnelSegment.java
private static Model createModel(Segment s, double segLen, TextureDescription[] tunnelTexturePalette, double endX, double endY, final TR tr) { Model mainModel = new Model(true, tr); mainModel.setDebugName("tunnelSegment main."); final int numPolys = s.getNumPolygons(); double startWidth = getStartWidth(s); double startHeight = getStartHeight(s); double endWidth = getEndWidth(s); double endHeight = getEndHeight(s); final FlickerLightType lightType = s.getFlickerLightType(); // TODO: Cleanup. final double startAngle1 = ((double) s.getStartAngle1() / 65535.) * 2. * Math.PI; final double startAngle2 = ((double) s.getStartAngle2() / 65535.) * 2. * Math.PI; final double startAngle = startAngle1; final double endAngle1 = ((double) s.getEndAngle1() / 65535.) * 2. * Math.PI; final double endAngle2 = ((double) s.getEndAngle2() / 65535.) * 2. * Math.PI; double endAngle = endAngle1; final double dAngleStart = (startAngle2 - startAngle1) / (double) numPolys; final double dAngleEnd = (endAngle2 - endAngle1) / (double) numPolys; final double startX = 0; final double startY = 0; final double zStart = 0; final double zEnd = segLen; final int numPolygonsMinusOne = s.getNumPolygons() - 1; final int lightPoly = s.getLightPolygon(); final boolean hasLight = lightPoly != -1; if (hasLight) { mainModel.setAnimateUV(true);//from www .j a v a 2s . c o m mainModel.setSmoothAnimation(false); if (lightType == FlickerLightType.noLight) { //Do nothing. } else if (lightType == FlickerLightType.off1p5Sec) { mainModel.setController(new Controller() { private final int off = (int) (Math.random() * 2000); @Override public double getCurrentFrame() { return (off + System.currentTimeMillis() % 2000) > 1500 ? 1 : 0; } @Override public void setDebugMode(boolean b) { //Not implemented. } }); } else if (lightType == FlickerLightType.on1p5Sec) { mainModel.setController(new Controller() { private final int off = (int) (Math.random() * 2000); @Override public double getCurrentFrame() { return (off + System.currentTimeMillis() % 2000) < 1500 ? 1 : 0; } @Override public void setDebugMode(boolean b) { //Not implemented. } }); } else if (lightType == FlickerLightType.on1Sec) { mainModel.setController(new Controller() { private final int off = (int) (Math.random() * 2000); @Override public double getCurrentFrame() { return (off + System.currentTimeMillis() % 2000) > 1000 ? 1 : 0; } @Override public void setDebugMode(boolean b) { //Not implemented. } }); } } //end (has light) final double[] noLightU = new double[] { 1, 1, 0, 0 }; final double[] noLightV = new double[] { 0, 1, 1, 0 }; final double[] lightOffU = new double[] { 1, 1, .5, .5 }; final double[] lightOffV = new double[] { .5, 1, 1, .5 }; final double[] lightOnU = new double[] { .5, .5, 0, 0 }; final double[] lightOnV = new double[] { .5, 1, 1, .5 }; double rotPeriod = (1000. * 32768.) / (double) s.getRotationSpeed(); final boolean reverseDirection = rotPeriod < 0; if (reverseDirection) rotPeriod *= -1; final int numFramesIfRotating = 30; final int numFramesIfStatic = 2; final boolean isRotating = !Double.isInfinite(rotPeriod); int numAnimFrames = isRotating ? numFramesIfRotating : numFramesIfStatic; if (isRotating) mainModel.setFrameDelayInMillis((int) (rotPeriod / (numAnimFrames))); final double animationDeltaRadians = isRotating ? ((reverseDirection ? 1 : -1) * (2 * Math.PI) / (double) numAnimFrames) : 0; //FRAME LOOP for (int frameIndex = 0; frameIndex < numAnimFrames; frameIndex++) { final Model m = new Model(false, tr); m.setDebugName("TunnelSegment frame " + frameIndex + " of " + numAnimFrames); final double frameAngleDeltaRadians = animationDeltaRadians * (double) frameIndex; double frameStartAngle = startAngle + frameAngleDeltaRadians; double frameEndAngle = endAngle + frameAngleDeltaRadians; final double frameStartAngle1 = startAngle1 + frameAngleDeltaRadians; final double frameStartAngle2 = startAngle2 + frameAngleDeltaRadians; final double frameEndAngle1 = endAngle + frameAngleDeltaRadians; double[] thisU = noLightU, thisV = noLightV;//Changeable u/v references, default to noLight // Poly quads for (int pi = 0; pi < numPolygonsMinusOne; pi++) { Vector3D p0 = segPoint(frameStartAngle, zStart, startWidth, startHeight, startX, startY); Vector3D p1 = segPoint(frameEndAngle, zEnd, endWidth, endHeight, endX, endY); Vector3D p2 = segPoint(frameEndAngle + dAngleEnd, zEnd, endWidth, endHeight, endX, endY); Vector3D p3 = segPoint(frameStartAngle + dAngleStart, zStart, startWidth, startHeight, startX, startY); TextureDescription tex = tunnelTexturePalette[s.getPolyTextureIndices().get(pi)]; if (pi == lightPoly && lightType != FlickerLightType.noLight) { if (frameIndex == 0) { thisU = lightOnU; thisV = lightOnV; } else { thisU = lightOffU; thisV = lightOffV; } /*try { final int flickerThresh = flt == FlickerLightType.off1p5Sec ? (int) (-.3 * (double) Integer.MAX_VALUE) : flt == FlickerLightType.on1p5Sec ? (int) (.4 * (double) Integer.MAX_VALUE) : flt == FlickerLightType.on1Sec ? (int) (.25 * (double) Integer.MAX_VALUE) : Integer.MAX_VALUE; m.addTickableAnimator(new Tickable() { @Override public void tick() { if (flickerRandom.transfer(Math.abs((int) System .currentTimeMillis())) > flickerThresh) st.setFrame(1); else st.setFrame(0); } }); } catch (Exception e) { e.printStackTrace(); }*/ } else { thisU = noLightU; thisV = noLightV; } // No light m.addTriangles(Triangle.quad2Triangles(new double[] { p3.getX(), p2.getX(), p1.getX(), p0.getX() }, new double[] { p3.getY(), p2.getY(), p1.getY(), p0.getY() }, new double[] { p3.getZ(), p2.getZ(), p1.getZ(), p0.getZ() }, thisU, thisV, tex, RenderMode.DYNAMIC, new Vector3D[] { new Vector3D(Math.cos(frameStartAngle + dAngleStart), -Math.sin(frameStartAngle + dAngleStart), 0), new Vector3D(Math.cos(frameEndAngle + dAngleEnd), -Math.sin(frameEndAngle + dAngleEnd), 0), new Vector3D(Math.cos(frameEndAngle), -Math.sin(frameEndAngle), 0), new Vector3D(Math.cos(frameStartAngle), -Math.sin(frameStartAngle), 0) }, 0)); frameStartAngle += dAngleStart; frameEndAngle += dAngleEnd; } // for(polygons) if (s.isCutout()) { // The slice quad // INWARD Vector3D p0 = segPoint(frameStartAngle, zStart, startWidth, startHeight, startX, startY); Vector3D p1 = segPoint(frameEndAngle, zEnd, endWidth, endHeight, endX, endY); Vector3D p2 = segPoint(frameEndAngle1, zEnd, 0, 0, endX, endY); Vector3D p3 = segPoint(frameStartAngle1, zStart, 0, 0, startX, startY); m.addTriangles(Triangle.quad2Triangles(new double[] { p3.getX(), p2.getX(), p1.getX(), p0.getX() }, new double[] { p3.getY(), p2.getY(), p1.getY(), p0.getY() }, new double[] { p3.getZ(), p2.getZ(), p1.getZ(), p0.getZ() }, new double[] { 1, 1, 0, 0 }, new double[] { 0, 1, 1, 0 }, tunnelTexturePalette[s.getPolyTextureIndices().get(numPolygonsMinusOne)], RenderMode.DYNAMIC, new Vector3D[] { new Vector3D(Math.cos(frameStartAngle + dAngleStart), -Math.sin(frameStartAngle + dAngleStart), 0), new Vector3D(Math.cos(frameEndAngle + dAngleEnd), -Math.sin(frameEndAngle + dAngleEnd), 0), new Vector3D(Math.cos(frameEndAngle), -Math.sin(frameEndAngle), 0), new Vector3D(Math.cos(frameStartAngle), -Math.sin(frameStartAngle), 0) }, 0)); // OUTWARD p3 = segPoint(frameStartAngle1, zStart, startWidth, startHeight, startX, startY); p2 = segPoint(frameEndAngle1, zEnd, endWidth, endHeight, endX, endY); p1 = segPoint(frameEndAngle1, zEnd, 0, 0, endX, endY); p0 = segPoint(frameStartAngle1, zStart, 0, 0, startX, startY); m.addTriangles(Triangle.quad2Triangles(new double[] { p3.getX(), p2.getX(), p1.getX(), p0.getX() }, new double[] { p3.getY(), p2.getY(), p1.getY(), p0.getY() }, new double[] { p3.getZ(), p2.getZ(), p1.getZ(), p0.getZ() }, new double[] { 1, 1, 0, 0 }, new double[] { 0, 1, 1, 0 }, tunnelTexturePalette[s.getPolyTextureIndices().get(numPolygonsMinusOne)], RenderMode.DYNAMIC, new Vector3D[] { new Vector3D(Math.cos(frameStartAngle + dAngleStart), -Math.sin(frameStartAngle + dAngleStart), 0), new Vector3D(Math.cos(frameEndAngle + dAngleEnd), -Math.sin(frameEndAngle + dAngleEnd), 0), new Vector3D(Math.cos(frameEndAngle), -Math.sin(frameEndAngle), 0), new Vector3D(Math.cos(frameStartAngle), -Math.sin(frameStartAngle), 0) }, 0)); } else { // The slice quad Vector3D p0 = segPoint(frameStartAngle, zStart, startWidth, startHeight, startX, startY); Vector3D p1 = segPoint(frameEndAngle, zEnd, endWidth, endHeight, endX, endY); Vector3D p2 = segPoint(frameEndAngle1, zEnd, endWidth, endHeight, endX, endY); Vector3D p3 = segPoint(frameStartAngle1, zStart, startWidth, startHeight, startX, startY); m.addTriangles(Triangle.quad2Triangles(new double[] { p3.getX(), p2.getX(), p1.getX(), p0.getX() }, new double[] { p3.getY(), p2.getY(), p1.getY(), p0.getY() }, new double[] { p3.getZ(), p2.getZ(), p1.getZ(), p0.getZ() }, new double[] { 1, 1, 0, 0 }, new double[] { 0, 1, 1, 0 }, tunnelTexturePalette[s.getPolyTextureIndices().get(numPolygonsMinusOne)], RenderMode.DYNAMIC, new Vector3D[] { new Vector3D(Math.cos(frameStartAngle + dAngleStart), -Math.sin(frameStartAngle + dAngleStart), 0), new Vector3D(Math.cos(frameEndAngle + dAngleEnd), -Math.sin(frameEndAngle + dAngleEnd), 0), new Vector3D(Math.cos(frameEndAngle), -Math.sin(frameEndAngle), 0), new Vector3D(Math.cos(frameStartAngle), -Math.sin(frameStartAngle), 0) }, 0)); } //end !cutout //if(numAnimFrames!=1)//Push frame if animated. mainModel.addFrame(m); } //end for(frames) return mainModel; }
From source file:org.jtrfp.trcl.obj.WorldObject.java
protected void attemptLoop() { if (LOOP) {//w w w .j ava 2 s . c o m final Vector3D camPos = tr.mainRenderer.get().getCamera().getCameraPosition(); double delta = position[0] - camPos.getX(); if (delta > TR.mapWidth / 2.) { position[0] -= TR.mapWidth; needToRecalcMatrix = true; } else if (delta < -TR.mapWidth / 2.) { position[0] += TR.mapWidth; needToRecalcMatrix = true; } delta = position[1] - camPos.getY(); if (delta > TR.mapWidth / 2.) { position[1] -= TR.mapWidth; needToRecalcMatrix = true; } else if (delta < -TR.mapWidth / 2.) { position[1] += TR.mapWidth; needToRecalcMatrix = true; } delta = position[2] - camPos.getZ(); if (delta > TR.mapWidth / 2.) { position[2] -= TR.mapWidth; needToRecalcMatrix = true; } else if (delta < -TR.mapWidth / 2.) { position[2] += TR.mapWidth; needToRecalcMatrix = true; } } //end if(LOOP) }
From source file:org.jtrfp.trcl.obj.WorldObject.java
/** * @param heading//from w w w. j a v a 2s. c o m * the heading to set */ public synchronized void setHeading(Vector3D nHeading) { heading[0] = nHeading.getX(); heading[1] = nHeading.getY(); heading[2] = nHeading.getZ(); needToRecalcMatrix = true; }
From source file:org.jtrfp.trcl.obj.WorldObject.java
/** * @param top// w ww. j a v a 2 s .c om * the top to set */ public synchronized void setTop(Vector3D nTop) { top[0] = nTop.getX(); top[1] = nTop.getY(); top[2] = nTop.getZ(); needToRecalcMatrix = true; }
From source file:org.jtrfp.trcl.obj.WorldObject.java
public synchronized void movePositionBy(Vector3D delta) { position[0] += delta.getX(); position[1] += delta.getY();/*from www . ja v a 2 s . c om*/ position[2] += delta.getZ(); notifyPositionChange(); }
From source file:org.jtrfp.trcl.SpacePartitioningGrid.java
public SpacePartitioningGrid(Vector3D size, double squareSize, double viewingRadius) { setSquareSize(squareSize);//from w w w. ja v a 2s . c o m setSquaresX((int) (size.getX() / squareSize)); setSquaresY((int) (size.getY() / squareSize)); setSquaresZ((int) (size.getZ() / squareSize)); setViewingRadius(viewingRadius); allocateSquares(); }
From source file:org.jtrfp.trcl.TerrainSystem.java
public TerrainSystem(final InterpolatingAltitudeMap altitude, final TextureMesh textureMesh, final double gridSquareSize, final SpacePartitioningGrid parent, final RenderableSpacePartitioningGrid terrainMirror, final TR tr, final TDFFile tdf, final boolean flatShading, final LoadingProgressReporter terrainReporter) { super(parent); final int numCores = Runtime.getRuntime().availableProcessors(); this.tr = tr; final int width = (int) altitude.getWidth(); int height = (int) altitude.getHeight(); this.gridSquareSize = gridSquareSize; this.heightScalar = tr.getWorld().sizeY / 2; final int chunkSideLength = TR.terrainChunkSideLengthInSquares; final double u[] = { 0, 1, 1, 0 }; final double v[] = { 0, 0, 1, 1 }; final double cu[] = { 0, 1, 1, 0 }; final double cv[] = { 1, 1, 0, 0 }; // Come up with a point list for tunnel entrances and exits TDFFile.Tunnel[] tunnels = tdf.getTunnels(); final HashMap<Integer, TunnelPoint> points = new HashMap<Integer, TunnelPoint>(); final HashMap<String, TDFFile.Tunnel> tunnelsByName = new HashMap<String, TDFFile.Tunnel>(); if (tunnels != null) {// Null means no tunnels for (int i = 0; i < tunnels.length; i++) { final TDFFile.Tunnel tun = tunnels[i]; if (tun.getEntranceLogic() != TunnelLogic.invisible) { final TunnelPoint tp = new TunnelPoint(tun, true); points.put(tp.hashCode(), tp); }/*from w w w . j av a2s . c om*/ if (tun.getExitLogic() != TunnelLogic.invisible) { final TunnelPoint tp = new TunnelPoint(tun, false); points.put(tp.hashCode(), tp); tunnelsByName.put(tun.getTunnelLVLFile(), tunnels[i]); } //end if(invisible) } // end for(tunnels) } // end if(tunnels) final LoadingProgressReporter[] reporters = terrainReporter.generateSubReporters(256 / chunkSideLength); int reporterIndex = 0; TRFutureTask<Void>[] rowTasks = new TRFutureTask[numCores * 2]; int taskIdx = 0; // For each chunk for (int gZ = 0; gZ < height; gZ += chunkSideLength) { reporters[reporterIndex++].complete(); final int _gZ = gZ; rowTasks[taskIdx++] = tr.getThreadManager().submitToThreadPool(new Callable<Void>() { @Override public Void call() throws Exception { for (int gX = 0; gX < width; gX += chunkSideLength) { // GROUND {// Start scope final double objectX = Math .round(((double) gX + ((double) chunkSideLength / 2.)) * gridSquareSize); final double objectZ = Math .round(((double) _gZ + ((double) chunkSideLength / 2.)) * gridSquareSize); final double objectY = Math.round(altitude.heightAt(gX, _gZ) * heightScalar); final Model m = new Model(false, tr); // for each square for (int cZ = _gZ; cZ < _gZ + chunkSideLength; cZ++) { for (int cX = gX; cX < gX + chunkSideLength; cX++) { final double hTL = altitude.heightAt(cX, cZ) * heightScalar; final double hTR = altitude.heightAt((cX + 1), cZ) * heightScalar; final double hBR = altitude.heightAt((cX + 1), (cZ + 1)) * heightScalar; final double hBL = altitude.heightAt(cX, (cZ + 1)) * heightScalar; final double xPos = cX * gridSquareSize; final double zPos = cZ * gridSquareSize; Vector3D norm0, norm1, norm2, norm3; Vector3D norm = altitude.normalAt(cX, cZ); norm3 = new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3).normalize(); norm = altitude.normalAt(cX + 1, cZ); norm2 = new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3).normalize(); norm = altitude.normalAt(cX + 1, cZ + 1); norm1 = new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3).normalize(); norm = altitude.normalAt(cX, cZ + 1); norm0 = new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3).normalize(); if (flatShading) norm0 = norm1 = norm2 = norm3 = altitude.normalAt(cX + .5, cZ + .5); final Integer tpi = cX + cZ * 256; TextureDescription td = (TextureDescription) (points.containsKey(tpi) ? points.get(tpi).getTexture() : textureMesh.textureAt(cX, cZ)); Triangle[] tris = Triangle.quad2Triangles( // COUNTER-CLOCKWISE // //x new double[] { xPos - objectX, xPos + gridSquareSize - objectX, xPos + gridSquareSize - objectX, xPos - objectX }, new double[] { hBL - objectY, hBR - objectY, hTR - objectY, hTL - objectY }, new double[] { zPos + gridSquareSize - objectZ, zPos + gridSquareSize - objectZ, zPos - objectZ, zPos - objectZ }, u, v, td, RenderMode.STATIC, new Vector3D[] { norm0, norm1, norm2, norm3 }, cX + cZ % 4); m.addTriangle(tris[0]); m.addTriangle(tris[1]); } // end for(cX) } // end for(cZ) // Add to grid if (m.finalizeModel().getTriangleList() != null) { final TerrainChunk chunkToAdd = new TerrainChunk(tr, m, altitude); final double[] chunkPos = chunkToAdd.getPosition(); chunkPos[0] = objectX; chunkPos[1] = objectY; chunkPos[2] = objectZ; chunkToAdd.notifyPositionChange(); add(chunkToAdd); } else { System.out.println("Rejected chunk: " + m.getDebugName()); } } // end scope {// start scope ///// CEILING final double objectX = Math .round(((double) gX + ((double) chunkSideLength / 2.)) * gridSquareSize); final double objectZ = Math .round(((double) _gZ + ((double) chunkSideLength / 2.)) * gridSquareSize); final double objectY = Math .round((2. - altitude.heightAt(gX, _gZ)) * heightScalar + Y_NUDGE); final Model m = new Model(false, tr); // for each square for (int cZ = _gZ; cZ < _gZ + chunkSideLength; cZ++) { for (int cX = gX; cX < gX + chunkSideLength; cX++) { final double hTL = (2. - altitude.heightAt(cX, cZ)) * heightScalar + Y_NUDGE; final double hTR = (2. - altitude.heightAt((cX + 1), cZ)) * heightScalar + Y_NUDGE; final double hBR = (2. - altitude.heightAt((cX + 1), (cZ + 1))) * heightScalar + Y_NUDGE; final double hBL = (2. - altitude.heightAt(cX, (cZ + 1))) * heightScalar + Y_NUDGE; final double xPos = cX * gridSquareSize; final double zPos = cZ * gridSquareSize; Vector3D norm0, norm1, norm2, norm3; Vector3D norm = altitude.normalAt(cX, cZ); norm3 = altitude.heightAt(cX, cZ) < .9 ? new Vector3D(norm.getX() * 3, norm.getY() * -1, norm.getZ() * 3) .normalize() : new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3) .normalize(); norm = altitude.normalAt(cX + 1, cZ); norm2 = altitude.heightAt(cX + 1, cZ) < .9 ? new Vector3D(norm.getX() * 3, norm.getY() * -1, norm.getZ() * 3) .normalize() : new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3) .normalize(); norm = altitude.normalAt(cX + 1, cZ + 1); norm1 = altitude.heightAt(cX + 1, cZ + 1) < .9 ? new Vector3D(norm.getX() * 3, norm.getY() * -1, norm.getZ() * 3) .normalize() : new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3) .normalize(); norm = altitude.normalAt(cX, cZ + 1); norm0 = altitude.heightAt(cX, cZ + 1) < .9 ? new Vector3D(norm.getX() * 3, norm.getY() * -1, norm.getZ() * 3) .normalize() : new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3) .normalize(); if (flatShading) norm0 = norm1 = norm2 = norm3 = altitude.normalAt(cX + .5, cZ + .5); // Ceiling texture cell X (Z in this engine) value // is offset by 10. // No tunnelpoints on ceiling TextureDescription td = (TextureDescription) (textureMesh.textureAt(cX, cZ + 10)); norm = new Vector3D(norm.getX() * 3, norm.getY(), norm.getZ() * 3).normalize();// Exaggerate // features. Triangle[] tris = Triangle.quad2Triangles( // CLOCKWISE (else backface culling will eat // it) new double[] { xPos - objectX, xPos + gridSquareSize - objectX, xPos + gridSquareSize - objectX, xPos - objectX }, // x new double[] { hTL - objectY, hTR - objectY, hBR - objectY, hBL - objectY }, new double[] { zPos - objectZ, zPos - objectZ, zPos + gridSquareSize - objectZ, zPos + gridSquareSize - objectZ }, cu, cv, td, RenderMode.STATIC, new Vector3D[] { norm3, norm2, norm1, norm0 }, cX + cZ % 4); m.addTriangle(tris[0]); m.addTriangle(tris[1]); } // end for(cX) } // end for(cZ) // Add to grid if (m.finalizeModel().getTriangleList() != null) { final TerrainChunk chunkToAdd = new TerrainChunk(tr, m, altitude); final double[] chunkPos = chunkToAdd.getPosition(); chunkPos[0] = objectX; chunkPos[1] = objectY; chunkPos[2] = objectZ; chunkToAdd.notifyPositionChange(); chunkToAdd.setCeiling(true); terrainMirror.add(chunkToAdd); } else { System.out.println("Rejected chunk: " + m.getDebugName()); } } // end scope(CEILING) } // end for(gX) return null; } }); if (taskIdx >= rowTasks.length) taskIdx = 0; } // end for(gZ) terrainMirror.deactivate(); }