You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

664 line
30 KiB

  1. package roadtrip;
  2. import com.jme3.app.SimpleApplication;
  3. import com.jme3.audio.AudioNode;
  4. import com.jme3.audio.AudioSource.Status;
  5. import com.jme3.bullet.BulletAppState;
  6. import com.jme3.bullet.PhysicsSpace;
  7. import com.jme3.bullet.collision.shapes.BoxCollisionShape;
  8. import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
  9. import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
  10. import com.jme3.bullet.control.BetterCharacterControl;
  11. import com.jme3.bullet.control.RigidBodyControl;
  12. import com.jme3.bullet.control.VehicleControl;
  13. import com.jme3.input.ChaseCamera;
  14. import com.jme3.input.KeyInput;
  15. import com.jme3.input.controls.ActionListener;
  16. import com.jme3.input.controls.KeyTrigger;
  17. import com.jme3.light.DirectionalLight;
  18. import com.jme3.material.Material;
  19. import com.jme3.math.ColorRGBA;
  20. import com.jme3.math.FastMath;
  21. import com.jme3.math.Quaternion;
  22. import com.jme3.math.Vector3f;
  23. import com.jme3.scene.CameraNode;
  24. import com.jme3.scene.Geometry;
  25. import com.jme3.scene.Node;
  26. import com.jme3.scene.Spatial;
  27. import com.jme3.scene.control.CameraControl.ControlDirection;
  28. import com.jme3.scene.shape.Box;
  29. import com.jme3.scene.shape.Cylinder;
  30. import com.jme3.terrain.geomipmap.TerrainGrid;
  31. import com.jme3.terrain.geomipmap.TerrainGridListener;
  32. import com.jme3.terrain.geomipmap.TerrainGridLodControl;
  33. import com.jme3.terrain.geomipmap.TerrainLodControl;
  34. import com.jme3.terrain.geomipmap.TerrainQuad;
  35. import com.jme3.terrain.geomipmap.grid.FractalTileLoader;
  36. import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
  37. import com.jme3.terrain.noise.ShaderUtils;
  38. import com.jme3.terrain.noise.basis.FilteredBasis;
  39. import com.jme3.terrain.noise.filter.IterativeFilter;
  40. import com.jme3.terrain.noise.filter.OptimizedErode;
  41. import com.jme3.terrain.noise.filter.PerturbFilter;
  42. import com.jme3.terrain.noise.filter.SmoothFilter;
  43. import com.jme3.terrain.noise.fractal.FractalSum;
  44. import com.jme3.terrain.noise.modulator.NoiseModulator;
  45. import com.jme3.texture.Texture;
  46. import java.util.LinkedList;
  47. import java.util.List;
  48. /**
  49. *
  50. * @author dejvino
  51. */
  52. public class RoadTrip extends SimpleApplication implements ActionListener {
  53. public static void main(String[] args)
  54. {
  55. RoadTrip app = new RoadTrip();
  56. app.start();
  57. }
  58. public static boolean DEBUG = false;//true;
  59. private BulletAppState bulletAppState;
  60. private ChaseCamera chaseCam;
  61. // START Terrain
  62. private Material mat_terrain;
  63. private TerrainGrid terrain;
  64. private float grassScale = 64;
  65. private float dirtScale = 64;
  66. private float rockScale = 64;
  67. private FractalSum base;
  68. private PerturbFilter perturb;
  69. private OptimizedErode therm;
  70. private SmoothFilter smooth;
  71. private IterativeFilter iterate;
  72. // END Terrain
  73. private List<VehicleNode> vehicles = new LinkedList<>();
  74. // START Player
  75. private Node playerNode;
  76. private BetterCharacterControl playerPersonControl;
  77. private Vector3f jumpForce = new Vector3f(0, 3000, 0);
  78. private Vector3f walkDir = new Vector3f();
  79. private VehicleNode playerVehicleNode;
  80. // END Player
  81. private PhysicsSpace getPhysicsSpace(){
  82. return bulletAppState.getPhysicsSpace();
  83. }
  84. @Override
  85. public void simpleInitApp() {
  86. bulletAppState = new BulletAppState();
  87. stateManager.attach(bulletAppState);
  88. if (DEBUG) bulletAppState.getPhysicsSpace().enableDebug(assetManager);
  89. PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
  90. setupKeys();
  91. //audioRenderer.setEnvironment(Environment.Dungeon);
  92. //AL10.alDistanceModel(AL11.AL_EXPONENT_DISTANCE);
  93. // Environment
  94. DirectionalLight dl = new DirectionalLight();
  95. dl.setColor(ColorRGBA.LightGray);
  96. dl.setDirection(new Vector3f(1, -1, 1));
  97. rootNode.addLight(dl);
  98. addMap();
  99. addCar();
  100. addCar();
  101. addCar();
  102. addCar();
  103. addCar();
  104. addPerson();
  105. addPerson();
  106. addPerson();
  107. addPerson();
  108. addPerson();
  109. addPerson();
  110. addPerson();
  111. addPlayer();
  112. chaseCam = new ChaseCamera(cam, playerNode, inputManager);
  113. chaseCam.setSmoothMotion(true);
  114. }
  115. private void setupKeys() {
  116. inputManager.clearMappings();
  117. inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
  118. inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
  119. inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
  120. inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
  121. inputManager.addMapping("Revs", new KeyTrigger(KeyInput.KEY_X));
  122. inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
  123. inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
  124. inputManager.addMapping("Esc", new KeyTrigger(KeyInput.KEY_ESCAPE));
  125. inputManager.addListener(this, "Lefts");
  126. inputManager.addListener(this, "Rights");
  127. inputManager.addListener(this, "Ups");
  128. inputManager.addListener(this, "Downs");
  129. inputManager.addListener(this, "Revs");
  130. inputManager.addListener(this, "Space");
  131. inputManager.addListener(this, "Reset");
  132. inputManager.addListener(this, "Esc");
  133. }
  134. private void addCar()
  135. {
  136. Node vehicleModel = new Node("VehicleModel");
  137. VehicleInstance vehicleInstance = VehicleInstance.createVehicle(vehicles.size() % VehicleInstance.getVehicleTypesCount());
  138. vehicleInstance.brakeForce = vehicleInstance.accelerationForce;
  139. Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
  140. mat.getAdditionalRenderState().setWireframe(true);
  141. mat.setColor("Color", ColorRGBA.Black);
  142. //Create four wheels and add them at their locations
  143. Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0
  144. Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0
  145. float radius = 1.0f;
  146. float restLength = 0.3f;
  147. float yOff = 0.5f;
  148. float xOff = 1.6f;
  149. float zOff = 2f;
  150. Material matBody = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
  151. matBody.setFloat("Shininess", 32f);
  152. matBody.setBoolean("UseMaterialColors", true);
  153. matBody.setColor("Ambient", ColorRGBA.Black);
  154. matBody.setColor("Diffuse", ColorRGBA.Red);
  155. matBody.setColor("Specular", ColorRGBA.White);
  156. if (vehicleInstance.carType == VehicleInstance.WEAK) {
  157. Spatial carBody = getAssetManager().loadModel("Models/rivercrossing.j3o");
  158. carBody.setLocalScale(1.1f, 0.8f, 0.8f);
  159. carBody.setLocalTranslation(0f, -1f, 0f);
  160. carBody.rotate(0f, 3.1415f, 0f);
  161. vehicleModel.attachChild(carBody);
  162. } else {
  163. Geometry carBody = new Geometry("car body", new Box(new Vector3f(0.0f, 1f, 0.0f), 1.4f, 0.5f, 3.6f));
  164. carBody.setMaterial(matBody);
  165. vehicleModel.attachChild(carBody);
  166. }
  167. //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0
  168. //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0
  169. CompoundCollisionShape compoundShape = new CompoundCollisionShape();
  170. BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.4f, 0.5f, 3.6f));
  171. compoundShape.addChildShape(box, new Vector3f(0, 1, 0));
  172. if (vehicleInstance.carType == VehicleInstance.TRUCK) {
  173. BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.4f, 0.8f, 1.0f));
  174. compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, 2f));
  175. Geometry carCabin = new Geometry("car cabin", new Box(new Vector3f(0, 2, 2f), 1.4f, 0.8f, 1.0f));
  176. carCabin.setMaterial(matBody);
  177. vehicleModel.attachChild(carCabin);
  178. } else if (vehicleInstance.carType == VehicleInstance.SPORT) {
  179. BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.2f, 0.6f, 2.0f));
  180. compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, -1f));
  181. Geometry carCabin = new Geometry("car cabin", new Box(new Vector3f(0, 2, -1f), 1.2f, 0.6f, 2.0f));
  182. carCabin.setMaterial(matBody);
  183. vehicleModel.attachChild(carCabin);
  184. }
  185. VehicleControl vehicleControl = new VehicleControl(compoundShape, 500);
  186. //setting suspension values for wheels, this can be a bit tricky
  187. //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en
  188. float stiffness = 30.0f;//200=f1 car
  189. float compValue = .1f; //(should be lower than damp)
  190. float dampValue = .2f;
  191. vehicleControl.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
  192. vehicleControl.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
  193. vehicleControl.setSuspensionStiffness(stiffness);
  194. vehicleControl.setMaxSuspensionForce(10000.0f);
  195. Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.2f, true);
  196. Node node1 = new Node("wheel 1 node");
  197. Geometry wheels1 = new Geometry("wheel 1", wheelMesh);
  198. node1.attachChild(wheels1);
  199. wheels1.rotate(0, FastMath.HALF_PI, 0);
  200. wheels1.setMaterial(mat);
  201. vehicleControl.addWheel(node1, new Vector3f(-xOff, yOff, zOff),
  202. wheelDirection, wheelAxle, restLength, radius, true);
  203. Node node2 = new Node("wheel 2 node");
  204. Geometry wheels2 = new Geometry("wheel 2", wheelMesh);
  205. node2.attachChild(wheels2);
  206. wheels2.rotate(0, FastMath.HALF_PI, 0);
  207. wheels2.setMaterial(mat);
  208. vehicleControl.addWheel(node2, new Vector3f(xOff, yOff, zOff),
  209. wheelDirection, wheelAxle, restLength, radius, true);
  210. Node node3 = new Node("wheel 3 node");
  211. Geometry wheels3 = new Geometry("wheel 3", wheelMesh);
  212. node3.attachChild(wheels3);
  213. wheels3.rotate(0, FastMath.HALF_PI, 0);
  214. wheels3.setMaterial(mat);
  215. vehicleControl.addWheel(node3, new Vector3f(-xOff, yOff, -zOff),
  216. wheelDirection, wheelAxle, restLength, radius, false);
  217. Node node4 = new Node("wheel 4 node");
  218. Geometry wheels4 = new Geometry("wheel 4", wheelMesh);
  219. node4.attachChild(wheels4);
  220. wheels4.rotate(0, FastMath.HALF_PI, 0);
  221. wheels4.setMaterial(mat);
  222. vehicleControl.addWheel(node4, new Vector3f(xOff, yOff, -zOff),
  223. wheelDirection, wheelAxle, restLength, radius, false);
  224. vehicleModel.attachChild(node1);
  225. vehicleModel.attachChild(node2);
  226. vehicleModel.attachChild(node3);
  227. vehicleModel.attachChild(node4);
  228. if (vehicleInstance.carType == VehicleInstance.TRUCK) {
  229. Node node5 = new Node("wheel 5 node");
  230. Geometry wheels5 = new Geometry("wheel 5", wheelMesh);
  231. node5.attachChild(wheels5);
  232. wheels5.rotate(0, FastMath.HALF_PI, 0);
  233. wheels5.setMaterial(mat);
  234. vehicleControl.addWheel(node5, new Vector3f(-xOff, yOff, 2.1f* -zOff),
  235. wheelDirection, wheelAxle, restLength, radius, false);
  236. Node node6 = new Node("wheel 6 node");
  237. Geometry wheels6 = new Geometry("wheel 6", wheelMesh);
  238. node6.attachChild(wheels6);
  239. wheels6.rotate(0, FastMath.HALF_PI, 0);
  240. wheels6.setMaterial(mat);
  241. vehicleControl.addWheel(node6, new Vector3f(xOff, yOff, 2.1f* -zOff),
  242. wheelDirection, wheelAxle, restLength, radius, false);
  243. vehicleModel.attachChild(node5);
  244. vehicleModel.attachChild(node6);
  245. }
  246. vehicleControl.getWheel(0).setFrictionSlip(0.8f);
  247. vehicleControl.getWheel(1).setFrictionSlip(0.8f);
  248. vehicleControl.getWheel(2).setFrictionSlip(0.6f);
  249. vehicleControl.getWheel(3).setFrictionSlip(0.6f);
  250. if (vehicleInstance.carType == VehicleInstance.TRUCK) {
  251. vehicleControl.getWheel(4).setFrictionSlip(0.6f);
  252. vehicleControl.getWheel(5).setFrictionSlip(0.6f);
  253. }
  254. vehicleControl.setPhysicsLocation(new Vector3f(5f, 30f, 5f));
  255. VehicleNode vehicle = new VehicleNode("VehicleNode",
  256. vehicleInstance, vehicleControl, vehicleModel);
  257. vehicle.attachChild(vehicleModel);
  258. vehicle.engineAudio = new AudioNode(assetManager, "Sounds/engine.ogg", false);
  259. vehicle.engineAudio.setPositional(true);
  260. vehicle.engineAudio.setLooping(true);
  261. vehicle.engineAudio.setReverbEnabled(true);
  262. vehicle.engineAudio.setRefDistance(5);
  263. vehicle.engineAudio.setMaxDistance(1000000);
  264. vehicle.attachChild(vehicle.engineAudio);
  265. vehicle.wheelsAudio = new AudioNode(assetManager, "Sounds/wheels.ogg", false);
  266. vehicle.wheelsAudio.setPositional(true);
  267. vehicle.wheelsAudio.setLooping(true);
  268. //wheelsAudio.setReverbEnabled(true);
  269. vehicle.wheelsAudio.setRefDistance(1f);
  270. vehicle.wheelsAudio.setMaxDistance(1000000f);
  271. vehicle.wheelsAudio.play();
  272. vehicle.attachChild(vehicle.wheelsAudio);
  273. vehicle.wheelSlipAudio = new AudioNode(assetManager, "Sounds/wheel-slip.ogg", false);
  274. vehicle.wheelSlipAudio.setPositional(true);
  275. vehicle.wheelSlipAudio.setLooping(true);
  276. //wheelsAudio.setReverbEnabled(true);
  277. vehicle.wheelSlipAudio.setRefDistance(5);
  278. vehicle.wheelSlipAudio.setMaxDistance(1000000);
  279. vehicle.wheelSlipAudio.play();
  280. vehicle.attachChild(vehicle.wheelSlipAudio);
  281. vehicle.addControl(vehicleControl);
  282. getPhysicsSpace().add(vehicleControl);
  283. vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 28f, 12f + (float)Math.random() * 40f));
  284. vehicles.add(vehicle);
  285. rootNode.attachChild(vehicle);
  286. }
  287. private Node addPerson() {
  288. Spatial personModel = assetManager.loadModel("Models/person.j3o");
  289. Node person = new Node("person");
  290. person.attachChild(personModel);
  291. BetterCharacterControl personControl = new BetterCharacterControl(1f, 4f, 10f);
  292. /*personModel.setLocalTranslation(0f, -1f, 0f);
  293. BoxCollisionShape personShape = new BoxCollisionShape(new Vector3f(0.5f, 2f, 0.5f));
  294. RigidBodyControl personControl = new RigidBodyControl(personShape, 80f);/**/
  295. person.addControl(personControl);
  296. /**/personControl.setJumpForce(new Vector3f(0,5f,0));
  297. personControl.setGravity(new Vector3f(0,1f,0));
  298. personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f));/**/
  299. //personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f));
  300. getPhysicsSpace().add(personControl);
  301. //getPhysicsSpace().addAll(person);
  302. rootNode.attachChild(person);
  303. Vector3f dir = new Vector3f((float)Math.random() * 2f - 1f, 0f, (float)Math.random() * 2f - 1f);
  304. personControl.setViewDirection(dir);
  305. personControl.setWalkDirection(dir);
  306. return person;
  307. }
  308. private void addPlayer()
  309. {
  310. playerNode = addPerson();
  311. playerPersonControl = playerNode.getControl(BetterCharacterControl.class);
  312. }
  313. private void addMap() {
  314. // TERRAIN TEXTURE material
  315. this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
  316. // Parameters to material:
  317. // regionXColorMap: X = 1..4 the texture that should be appliad to state X
  318. // regionX: a Vector3f containing the following information:
  319. // regionX.x: the start height of the region
  320. // regionX.y: the end height of the region
  321. // regionX.z: the texture scale for the region
  322. // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
  323. // slopeColorMap: the texture to be used for cliffs, and steep mountain sites
  324. // slopeTileFactor: the texture scale for slopes
  325. // terrainSize: the total size of the terrain (used for scaling the texture)
  326. // GRASS texture
  327. Texture grass = this.assetManager.loadTexture("Textures/solid-grass.png");
  328. grass.setWrap(Texture.WrapMode.Repeat);
  329. Texture dirt = this.assetManager.loadTexture("Textures/solid-road.png");
  330. dirt.setWrap(Texture.WrapMode.Repeat);
  331. Texture rock = this.assetManager.loadTexture("Textures/solid-stone.png");
  332. rock.setWrap(Texture.WrapMode.Repeat);
  333. this.mat_terrain.setTexture("region1ColorMap", dirt);
  334. this.mat_terrain.setVector3("region1", new Vector3f(0, 80, this.dirtScale));
  335. this.mat_terrain.setTexture("region2ColorMap", grass);
  336. this.mat_terrain.setVector3("region2", new Vector3f(100, 160, this.grassScale));
  337. this.mat_terrain.setTexture("region3ColorMap", rock);
  338. this.mat_terrain.setVector3("region3", new Vector3f(190, 240, this.rockScale));
  339. this.mat_terrain.setTexture("region4ColorMap", dirt);
  340. this.mat_terrain.setVector3("region4", new Vector3f(250, 350, this.dirtScale));
  341. this.mat_terrain.setTexture("slopeColorMap", rock);
  342. this.mat_terrain.setFloat("slopeTileFactor", 32);
  343. this.mat_terrain.setFloat("terrainSize", 513);
  344. this.base = new FractalSum();
  345. this.base.setRoughness(0.7f);
  346. this.base.setFrequency(1.0f);
  347. this.base.setAmplitude(1.0f);
  348. this.base.setLacunarity(2.12f);
  349. this.base.setOctaves(8);
  350. this.base.setScale(0.02125f);
  351. this.base.addModulator(new NoiseModulator() {
  352. @Override
  353. public float value(float... in) {
  354. return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1);
  355. }
  356. });
  357. FilteredBasis ground = new FilteredBasis(this.base);
  358. this.perturb = new PerturbFilter();
  359. this.perturb.setMagnitude(0.119f);
  360. this.therm = new OptimizedErode();
  361. this.therm.setRadius(5);
  362. this.therm.setTalus(0.011f);
  363. this.smooth = new SmoothFilter();
  364. this.smooth.setRadius(1);
  365. this.smooth.setEffect(0.7f);
  366. this.iterate = new IterativeFilter();
  367. this.iterate.addPreFilter(this.perturb);
  368. this.iterate.addPostFilter(this.smooth);
  369. this.iterate.setFilter(this.therm);
  370. this.iterate.setIterations(2);
  371. ground.addPreFilter(this.iterate);
  372. this.terrain = new TerrainGrid("terrain", 64 + 1, 256 + 1, new FractalTileLoader(ground, 300f));
  373. this.terrain.setMaterial(this.mat_terrain);
  374. this.terrain.setLocalTranslation(0, -200, 0);
  375. this.terrain.setLocalScale(2f, 1f, 2f);
  376. this.rootNode.attachChild(this.terrain);
  377. TerrainLodControl control = new TerrainGridLodControl(this.terrain, this.getCamera());
  378. control.setLodCalculator(new DistanceLodCalculator(64 + 1, 2.7f)); // patch size, and a multiplier
  379. this.terrain.addControl(control);
  380. terrain.addListener(new TerrainGridListener() {
  381. @Override
  382. public void gridMoved(Vector3f newCenter) {
  383. }
  384. @Override
  385. public void tileAttached(Vector3f cell, TerrainQuad quad) {
  386. while(quad.getControl(RigidBodyControl.class)!=null){
  387. quad.removeControl(RigidBodyControl.class);
  388. }
  389. quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
  390. bulletAppState.getPhysicsSpace().add(quad);
  391. }
  392. @Override
  393. public void tileDetached(Vector3f cell, TerrainQuad quad) {
  394. if (quad.getControl(RigidBodyControl.class) != null) {
  395. bulletAppState.getPhysicsSpace().remove(quad);
  396. quad.removeControl(RigidBodyControl.class);
  397. }
  398. }
  399. });
  400. }
  401. @Override
  402. public void simpleUpdate(float tpf) {
  403. Vector3f playerLocation = playerNode.getWorldTranslation();
  404. Vector3f newLocation = new Vector3f(playerLocation).add(new Vector3f(-1f, 1.5f, 2.4f).mult(20f));
  405. /*cam.setLocation(new Vector3f(cam.getLocation()).interpolate(newLocation, Math.min(tpf, 1f)));
  406. cam.lookAt(playerLocation, Vector3f.UNIT_Y);*/
  407. for (VehicleNode vehicle : vehicles) {
  408. vehicle.vehicleInstance.accelerationSmooth = (vehicle.vehicleInstance.accelerationSmooth + vehicle.vehicleInstance.accelerationValue * (tpf * 10f)) / (1 + tpf * 10f);
  409. vehicle.engineAudio.setVelocity(new Vector3f(0, 0, 0));
  410. vehicle.engineAudio.updateGeometricState();
  411. vehicle.engineAudio.setPitch(Math.max(0.5f, Math.min(vehicle.vehicleInstance.accelerationSmooth / vehicle.vehicleInstance.accelerationForce * 2f, 2.0f)));
  412. boolean engineRunning = (vehicle.vehicleInstance.accelerationValue > 0.01f || vehicle.vehicleInstance.accelerationValue < -0.01f);
  413. if ((vehicle.engineAudio.getStatus() == Status.Playing) && !engineRunning) {
  414. vehicle.engineAudio.stop();
  415. }
  416. if ((vehicle.engineAudio.getStatus() != Status.Playing) && engineRunning) {
  417. vehicle.engineAudio.play();
  418. }
  419. vehicle.wheelsAudio.updateGeometricState();
  420. float wheelRot = Math.abs(vehicle.vehicleControl.getWheel(0).getDeltaRotation() + vehicle.vehicleControl.getWheel(1).getDeltaRotation()) / tpf / 100f;
  421. // TODO: pitch
  422. //System.out.println("wheel rot: " + wheelRot);
  423. //wheelsAudio.setPitch(Math.max(0.5f, Math.min(wheelRot * 4f, 2.0f)));
  424. vehicle.wheelsAudio.setVolume(Math.max(0.0001f, Math.min(wheelRot, 1.0f)) - 0.0001f);
  425. if ((vehicle.wheelsAudio.getStatus() == Status.Playing) && wheelRot < 10f) {
  426. vehicle.wheelsAudio.stop();
  427. }
  428. if ((vehicle.wheelsAudio.getStatus() != Status.Playing) && wheelRot > 10f) {
  429. vehicle.wheelsAudio.play();
  430. }
  431. vehicle.wheelSlipAudio.updateGeometricState();
  432. float slipAll = 0f;
  433. for (int i = 0; i < vehicle.vehicleControl.getNumWheels(); i++) {
  434. slipAll += vehicle.vehicleControl.getWheel(i).getSkidInfo();
  435. }
  436. float slip = 1f - (slipAll) / vehicle.vehicleControl.getNumWheels();
  437. float wheelSlip = (slip * slip * slip * slip * slip * slip * slip) / tpf / 40f;
  438. // TODO: pitch
  439. //wheelsAudio.setPitch(Math.max(0.5f, Math.min(wheelRot * 4f, 2.0f)));
  440. vehicle.wheelSlipAudio.setVolume(Math.max(0.0001f, Math.min(wheelSlip, 1.0f)) - 0.0001f);
  441. }
  442. listener.setLocation(cam.getLocation());
  443. listener.setRotation(cam.getRotation());
  444. }
  445. @Override
  446. public void onAction(String binding, boolean value, float tpf) {
  447. if (playerVehicleNode == null) {
  448. float walkSpeed = 6f;
  449. if (binding.equals("Lefts")) {
  450. if (value) {
  451. walkDir.x -= walkSpeed;
  452. } else {
  453. walkDir.x += walkSpeed;
  454. }
  455. } else if (binding.equals("Rights")) {
  456. if (value) {
  457. walkDir.x += walkSpeed;
  458. } else {
  459. walkDir.x -= walkSpeed;
  460. }
  461. } else if (binding.equals("Ups")) {
  462. if (value) {
  463. walkDir.z -= walkSpeed;
  464. } else {
  465. walkDir.z += walkSpeed;
  466. }
  467. } else if (binding.equals("Downs")) {
  468. if (value) {
  469. walkDir.z += walkSpeed;
  470. } else {
  471. walkDir.z -= walkSpeed;
  472. }
  473. } else if (binding.equals("Reset")) {
  474. if (value) {
  475. System.out.println("Reset - to car");
  476. Vector3f playerPos = playerNode.getWorldTranslation();
  477. for (VehicleNode vehicle : vehicles) {
  478. Vector3f vehiclePos = vehicle.getWorldTranslation();
  479. float dist = playerPos.distance(vehiclePos);
  480. System.out.println(" .. dist: " + dist);
  481. if (dist < 5f) {
  482. playerVehicleNode = vehicle;
  483. playerNode.removeFromParent();
  484. playerNode.setLocalTranslation(0f, 0f, -1f);
  485. playerNode.setLocalRotation(Quaternion.DIRECTION_Z);
  486. playerNode.removeControl(playerPersonControl);
  487. playerVehicleNode.attachChild(playerNode);
  488. VehicleInstance playerVehicle = playerVehicleNode.vehicleInstance;
  489. playerVehicle.accelerationValue = 0;
  490. playerVehicle.steeringValue = 0;
  491. walkDir = new Vector3f();
  492. break;
  493. }
  494. }
  495. }
  496. }
  497. playerPersonControl.setWalkDirection(walkDir);
  498. playerPersonControl.setViewDirection(walkDir);
  499. } else {
  500. VehicleInstance playerVehicle = playerVehicleNode.vehicleInstance;
  501. VehicleControl playerVehicleControl = playerVehicleNode.vehicleControl;
  502. int playerCarType = playerVehicle.carType;
  503. float steerMax = 0.5f;
  504. if (playerCarType == VehicleInstance.TRUCK) {
  505. steerMax = 0.7f;
  506. }
  507. if (binding.equals("Lefts")) {
  508. if (value) {
  509. playerVehicle.steeringValue += steerMax;
  510. } else {
  511. playerVehicle.steeringValue += -steerMax;
  512. }
  513. playerVehicleControl.steer(playerVehicle.steeringValue);
  514. } else if (binding.equals("Rights")) {
  515. if (value) {
  516. playerVehicle.steeringValue += -steerMax;
  517. } else {
  518. playerVehicle.steeringValue += steerMax;
  519. }
  520. playerVehicleControl.steer(playerVehicle.steeringValue);
  521. } else if (binding.equals("Ups")) {
  522. if (value) {
  523. playerVehicle.accelerationValue += playerVehicle.accelerationForce;
  524. } else {
  525. playerVehicle.accelerationValue -= playerVehicle.accelerationForce;
  526. }
  527. playerVehicleControl.accelerate(2, playerVehicle.accelerationValue);
  528. playerVehicleControl.accelerate(3, playerVehicle.accelerationValue);
  529. if (playerCarType == VehicleInstance.TRUCK) {
  530. playerVehicleControl.accelerate(4, playerVehicle.accelerationValue);
  531. playerVehicleControl.accelerate(5, playerVehicle.accelerationValue);
  532. }
  533. } else if (binding.equals("Downs")) {
  534. float b;
  535. if (value) {
  536. playerVehicle.brakeForce = playerVehicle.accelerationForce;
  537. } else {
  538. playerVehicle.brakeForce = 0f;
  539. }
  540. playerVehicleControl.brake(0, playerVehicle.brakeForce);
  541. playerVehicleControl.brake(1, playerVehicle.brakeForce);
  542. } else if (binding.equals("Revs")) {
  543. if (value) {
  544. playerVehicle.accelerationValue += playerVehicle.accelerationForce;
  545. } else {
  546. playerVehicle.accelerationValue -= playerVehicle.accelerationForce;
  547. }
  548. playerVehicleControl.accelerate(2, -playerVehicle.accelerationValue);
  549. playerVehicleControl.accelerate(3, -playerVehicle.accelerationValue);
  550. if (playerCarType == VehicleInstance.TRUCK) {
  551. playerVehicleControl.accelerate(4, -playerVehicle.accelerationValue);
  552. playerVehicleControl.accelerate(5, -playerVehicle.accelerationValue);
  553. }
  554. } else if (binding.equals("Space")) {
  555. if (value) {
  556. playerVehicleControl.applyImpulse(jumpForce, Vector3f.ZERO);
  557. }
  558. } else if (binding.equals("Reset")) {
  559. if (value) {
  560. System.out.println("Reset - from car");
  561. playerNode.removeFromParent();
  562. playerNode.addControl(playerPersonControl);
  563. playerPersonControl.warp(playerVehicleNode.getLocalTranslation());
  564. rootNode.attachChild(playerNode);
  565. playerVehicleNode = null;
  566. walkDir = new Vector3f();
  567. /*playerVehicleControl.setPhysicsLocation(Vector3f.ZERO);
  568. playerVehicleControl.setPhysicsRotation(new Matrix3f());
  569. playerVehicleControl.setLinearVelocity(Vector3f.ZERO);
  570. playerVehicleControl.setAngularVelocity(Vector3f.ZERO);
  571. playerVehicleControl.resetSuspension();*/
  572. } else {
  573. }
  574. }
  575. }
  576. if (binding.equals("Esc")) {
  577. stop();
  578. }
  579. }
  580. }