2013 -- FYD file system content
[FYD.git] / src / gui / module3d / CModule3D.java
blob76af38544a2c24aa6810210ec2208637453e1df2
1 package gui.module3d;
3 import exceptions.network.NoClientCreatedException;
4 import gui.dialogs.CCreateNameDialogGui;
5 import gui.module3d.maps.CMap;
6 import gui.module3d.players.CCharacter;
7 import gui.module3d.weapons.CBulletControl;
8 import gui.module3d.weapons.CWeapon;
10 import java.io.IOException;
11 import java.util.Vector;
12 import java.util.logging.Level;
14 import network.CNetwork;
15 import network.client.CClient;
16 import utils.CKeysSettingsManager;
18 import com.jme3.app.SimpleApplication;
19 import com.jme3.asset.TextureKey;
20 import com.jme3.bullet.BulletAppState;
21 import com.jme3.bullet.PhysicsSpace;
22 import com.jme3.bullet.collision.PhysicsCollisionEvent;
23 import com.jme3.bullet.collision.PhysicsCollisionListener;
24 import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
25 import com.jme3.bullet.collision.shapes.SphereCollisionShape;
26 import com.jme3.bullet.control.CharacterControl;
27 import com.jme3.effect.ParticleEmitter;
28 import com.jme3.font.BitmapText;
29 import com.jme3.input.ChaseCamera;
30 import com.jme3.input.KeyInput;
31 import com.jme3.input.MouseInput;
32 import com.jme3.input.controls.ActionListener;
33 import com.jme3.input.controls.KeyTrigger;
34 import com.jme3.input.controls.MouseAxisTrigger;
35 import com.jme3.input.controls.MouseButtonTrigger;
36 import com.jme3.light.SpotLight;
37 import com.jme3.material.Material;
38 import com.jme3.math.ColorRGBA;
39 import com.jme3.math.FastMath;
40 import com.jme3.math.Quaternion;
41 import com.jme3.math.Vector3f;
42 import com.jme3.post.filters.DepthOfFieldFilter;
43 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
44 import com.jme3.scene.Geometry;
45 import com.jme3.scene.Node;
46 import com.jme3.scene.shape.Sphere;
47 import com.jme3.scene.shape.Sphere.TextureMode;
48 import com.jme3.system.AppSettings;
49 import com.jme3.texture.Texture;
52 public class CModule3D extends SimpleApplication
53 implements ActionListener,PhysicsCollisionListener {
55 private static CModule3D sInstance = null;
57 float hauteurbaseMap;
58 private BulletAppState bulletAppState;
59 private CharacterControl player;
60 private CMap map;
61 private Vector3f walkDirection = new Vector3f();
62 private boolean left = false, right = false, up = false, down = false, shoot = false;
63 DepthOfFieldFilter dofFilter;
64 Material stone_mat;
65 private CCharacter me;
66 ChaseCamera chaseCam;
67 Node perso;
68 private boolean etatpause=false;
69 SpotLight spot;
70 Boolean spotSwitch=true;
71 //Weapons
72 SphereCollisionShape normalbulletCollisionShape;
73 Material matnormalBullet;
74 Sphere normalbullet;
75 Geometry normalbulletgeo;
76 SphereCollisionShape rocketbulletCollisionShape;
77 Material matrocketBullet;
78 Sphere rocketbullet;
79 Geometry rocketbulletgeo;
80 ParticleEmitter effect;
82 // multiplayer var
83 //CCharacter addplayer = null;
84 //moveplayer moveplayer =null;
85 //shootplayer shootplayer=null;
86 private Vector<CCharacter> mPlayersList;
88 CCharacter enemmi;
89 public static CModule3D getInstance()
91 if (sInstance == null)
93 sInstance = new CModule3D();
94 if (sInstance!= null)
96 sInstance.createCanvas();
99 return sInstance;
103 private CModule3D()
105 super();
106 java.util.logging.Logger.getLogger("").setLevel(Level.SEVERE);
107 mPlayersList = new Vector<CCharacter>();
109 AppSettings cfg = new AppSettings(true);
111 cfg.setFrameRate(25); // set to less than or equal screen refresh rate
112 cfg.setVSync(true); // prevents page tearing
113 cfg.setFrequency(60); // set to screen refresh rate
114 cfg.setResolution(800, 600);
115 cfg.setFullscreen(true);
116 cfg.setSamples(2); // anti-aliasing
117 setSettings(cfg);
119 setDisplayStatView(false);
120 setDisplayFps(true);
122 /*TODO
125 setPauseOnLostFocus(true);
131 @Override
132 public void simpleInitApp() {
134 /** Set up Physics */
135 bulletAppState = new BulletAppState();
136 stateManager.attach(bulletAppState);
137 flyCam.setMoveSpeed(100);
139 map = new CMap (rootNode,assetManager,bulletAppState,viewPort,getCamera(),this);
141 setUpPersos();
142 prepareBullet();
143 setUpKeys();
144 initHUD();
145 initMaterials();
147 getPhysicsSpace().addCollisionListener(this);
149 // on indique au Thread client que le module 3d est chargé
150 CNetwork.s3DLoaded=true;
153 /** We over-write some navigational key mappings here, so we can
154 * add physics-controlled walking and jumping: */
157 private void setUpPersos(){
159 //enemmi = new CCharacter (rootNode,assetManager,bulletAppState,new Vector3f(-400,100, -80),"test");
161 // definition du personnage
162 // Create a appropriate physical shape for it
163 perso = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
164 String name = CCreateNameDialogGui.getInstance().getNamePlayerTextField().getText();
165 perso.setName(name);
166 perso.setShadowMode(ShadowMode.Cast);
168 CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(3f, 4f);
169 // Attach physical properties to model and PhysicsSpace
171 player = new CharacterControl(capsuleShape, 0.05f);
172 //quelques parametres
173 player.setJumpSpeed(30);
174 player.setFallSpeed(40);
175 player.setGravity(70);
176 //defini quand une pente est un obstacle ou pas
177 player.setMaxSlope(0.3f);
178 perso.addControl(player);
179 player.setPhysicsLocation(new Vector3f(-400,100, -80));
180 //defini le groupe d'appartenance dans le monde physique
181 //rootNode.attachChild(perso);
182 getPhysicsSpace().add(player);
184 me = new CCharacter(player,CCreateNameDialogGui.getInstance().getNamePlayerTextField().getText());
185 spot = new SpotLight();
186 spot.setSpotRange(100f); // distance
187 spot.setSpotInnerAngle(20f * FastMath.DEG_TO_RAD); // inner light cone (central beam)
188 spot.setSpotOuterAngle(30f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light)
189 spot.setColor(ColorRGBA.White.mult(2.0f)); // light color
190 spot.setPosition(player.getPhysicsLocation()); // shine from camera loc
191 spot.setDirection(player.getViewDirection()); // shine forward from camera loc
192 rootNode.addLight(spot);
196 public void setUpKeys() {
197 CKeysSettingsManager lKSM = CKeysSettingsManager.getInstance();
200 inputManager.clearMappings();
202 inputManager.addMapping("Up", lKSM.getMoveForwardKeyTrigger());
203 inputManager.addMapping("Down", lKSM.getMoveBackwardKeyTrigger());
204 inputManager.addMapping("Left", lKSM.getMoveLeftKeyTrigger());
205 inputManager.addMapping("Right", lKSM.getMoveRightKeyTrigger());
206 inputManager.addMapping("reload", lKSM.getReloadKeyTrigger());
207 inputManager.addMapping("LightSwitch", lKSM.getLightSwitchKeyTrigger());
209 inputManager.addMapping("nextWeapon", new MouseAxisTrigger(MouseInput.AXIS_WHEEL,true));
210 inputManager.addMapping("prevWeapon", new MouseAxisTrigger(MouseInput.AXIS_WHEEL,false));
211 inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
212 inputManager.addMapping("pause", new KeyTrigger(KeyInput.KEY_ESCAPE));
213 inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
215 inputManager.addListener(this, "Left");
216 inputManager.addListener(this, "Right");
217 inputManager.addListener(this, "Up");
218 inputManager.addListener(this, "Down");
219 inputManager.addListener(this, "Jump");
220 inputManager.addListener(this, "shoot");
221 inputManager.addListener(this, "nextWeapon");
222 inputManager.addListener(this, "prevWeapon");
223 inputManager.addListener(this, "reload");
224 inputManager.addListener(this, "pause");
225 inputManager.addListener(this, "LightSwitch");
229 protected void initHUD()
231 int width = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
232 int height = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
233 guiNode.detachAllChildren();
234 guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
235 BitmapText ch = new BitmapText(guiFont, false);
236 ch.setSize(guiFont.getCharSet().getRenderedSize()*2);
237 ch.setText("+"); // crosshairs
238 //center
239 ch.setLocalTranslation(width / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,height / 2 + ch.getLineHeight() / 2, 0);
240 guiNode.attachChild(ch);
242 CWeapon w= me.getCurrentWeapon();
243 BitmapText weapon = new BitmapText(guiFont,false);
244 weapon.setSize(guiFont.getCharSet().getRenderedSize());
245 weapon.setText(w.GetName());
246 weapon.setColor(ColorRGBA.Red);
247 weapon.setLocalTranslation(20,200, 0);
248 guiNode.attachChild(weapon);
250 BitmapText weaponbullet = new BitmapText(guiFont,false);
251 weaponbullet.setSize(guiFont.getCharSet().getRenderedSize());
252 String Ammo = w.GetcurrentAmmo()+" / "+ w.GetMaxAmmo();
253 weaponbullet.setText(Ammo);
254 weaponbullet.setColor(ColorRGBA.Red);
255 weaponbullet.setLocalTranslation(20,180, 0);
256 guiNode.attachChild(weaponbullet);
258 BitmapText lifecount = new BitmapText(guiFont,false);
259 lifecount.setSize(guiFont.getCharSet().getRenderedSize());
260 String life = "HP : "+me.getLife();
261 lifecount.setText(life);
262 lifecount.setColor(ColorRGBA.Red);
263 lifecount.setLocalTranslation(20,160, 0);
264 guiNode.attachChild(lifecount);
266 BitmapText ClientConnected = new BitmapText(guiFont,false);
267 ClientConnected.setSize(guiFont.getCharSet().getRenderedSize());
268 String clientsnames="connected : \n"+me.getName()+"\n";
269 for(int i=0;i<mPlayersList.size();i++)
270 clientsnames=clientsnames+mPlayersList.get(i).getName()+"\n";
271 ClientConnected.setText(clientsnames);
272 ClientConnected.setColor(ColorRGBA.Red);
273 ClientConnected.setLocalTranslation(width-100,height-100, 0);
274 guiNode.attachChild(ClientConnected);
278 /** These are our custom actions triggered by key presses.
279 * We do not walk yet, we just keep track of the direction the user pressed. */
280 public void onAction(String binding, boolean value, float tpf) {
282 if (binding.equals("Left"))
284 if (value) { left = true; } else { left = false; }
285 } else if (binding.equals("Right")) {
286 if (value) { right = true; } else { right = false; }
287 } else if (binding.equals("Up")) {
288 if (value) { up = true; } else { up = false; }
289 } else if (binding.equals("Down")) {
290 if (value) { down = true; } else { down = false; }
291 } else if (binding.equals("Jump")) {
292 player.jump();
293 } else if (binding.equals("pause")) {
294 if (value){
295 inputManager.setCursorVisible(!etatpause);
296 flyCam.setEnabled(etatpause);
297 etatpause=!etatpause;
300 } else if (binding.equals("shoot")) {
301 if (value) { shoot = true;
302 try {
303 CClient.getInstance().emitShootMessage(getPlayerX(),getPlayerY(),getPlayerZ(),getPlayerviewDirection(),me.getcurrentweapon());
304 } catch (IOException | NoClientCreatedException e) {
305 // TODO Auto-generated catch block
306 e.printStackTrace();
308 } else { shoot = false;
309 try {
310 CClient.getInstance().emitEndShootMessage();
311 } catch (IOException | NoClientCreatedException e) {
312 // TODO Auto-generated catch block
313 e.printStackTrace();
318 else if (value&&binding.equals("nextWeapon"))
320 me.nextweapon();
321 initHUD();
322 } else if (value&&binding.equals("prevWeapon"))
324 me.prevweapon();
325 initHUD();
327 }else if (value&&binding.equals("reload"))
329 CWeapon w=me.getCurrentWeapon();
330 w.Reload();
331 initHUD();
332 }else if (value&&binding.equals("LightSwitch"))
335 try {
336 CClient.getInstance().emitSwitchLightMessage();
337 } catch (IOException | NoClientCreatedException e) {
338 // TODO Auto-generated catch block
339 e.printStackTrace();
343 if(spotSwitch)
345 spot.setColor(ColorRGBA.Black.mult(2.0f));
346 }else
348 spot.setColor(ColorRGBA.White.mult(2.0f));
350 spotSwitch=!spotSwitch;
356 * This is the main event loop--walking happens here.
357 * We check in which direction the player is walking by interpreting
358 * the camera direction forward (camDir) and to the side (camLeft).
359 * The setWalkDirection() command is what lets a physics-controlled player walk.
360 * We also make sure here that the camera moves with player.
363 long lastshoottime;
364 @Override
365 public void simpleUpdate(float tpf) {
366 Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
367 Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
368 walkDirection.set(0, 0, 0);
370 map.changeShadowDirection(camDir);
372 //enemmi.Shoot(new Vector3f(1,0,0), 0);
374 if (left) { walkDirection.addLocal(camLeft); }
375 if (right) { walkDirection.addLocal(camLeft.negate()); }
376 if (up) { walkDirection.addLocal(camDir);
377 walkDirection.setY(0);}
378 if (down) { walkDirection.addLocal(camDir.negate());
379 walkDirection.setY(0);}
380 if (shoot)
382 CWeapon w= me.getCurrentWeapon();
383 if (System.currentTimeMillis()-lastshoottime>w.GetBulletFlow())
385 makeBullet();
386 lastshoottime=System.currentTimeMillis();
390 // bloquont le Upside-down de la camera
391 float[] angles=new float[3];
392 cam.getRotation().toAngles(angles);
393 //check the x rotation
394 Quaternion tmpQuat= new Quaternion();
395 if(angles[0]>(FastMath.HALF_PI-0.1f)){
396 angles[0]=(FastMath.HALF_PI-0.1f);
397 cam.setRotation(tmpQuat.fromAngles(angles));
398 }else if(angles[0]<-FastMath.HALF_PI+0.1f){
399 angles[0]=-FastMath.HALF_PI+0.1f;
400 cam.setRotation(tmpQuat.fromAngles(angles));
403 player.setWalkDirection(walkDirection);
404 spot.setPosition(player.getPhysicsLocation()); // shine from camera loc
405 spot.setDirection(cam.getDirection());
406 cam.setLocation(player.getPhysicsLocation());
408 int i=0;
409 while(i<mPlayersList.size() && mPlayersList.size()>0)
411 mPlayersList.get(i).Shoot();
412 i++;
416 // update for multiplayer message
417 if(addplayer!=null)
419 mPlayersList.add(addplayer);
420 initHUD();
421 addplayer=null;
424 if(moveplayer!=null)
426 // Recherche du joueur dans la lise des joueurs.
427 int i=0;
428 while(i<mPlayersList.size() && mPlayersList.size()>0)
430 if(mPlayersList.get(i).getName().matches(moveplayer.pPlayerName))
432 mPlayersList.get(i).setLocalPosition(moveplayer.move.add(0, 0.01f, 0));
433 mPlayersList.get(i).setViewDirection(moveplayer.viewdir);
434 break;
435 }else
437 i++;
440 moveplayer=null;
442 if(shootplayer!=null)
444 // Recherche du joueur dans la lise des joueurs.
445 int i=0;
446 while(i<mPlayersList.size() && mPlayersList.size()>0)
448 if(mPlayersList.get(i).getName().matches(shootplayer.pPlayerName))
450 mPlayersList.get(i).setLocalPosition(shootplayer.move.add(0, 0.01f, 0));
451 mPlayersList.get(i).setViewDirection(shootplayer.viewdir);
452 mPlayersList.get(i).Shoot(shootplayer.viewdir, shootplayer.weaponid);
453 break;
454 }else
456 i++;
459 shootplayer=null;
463 //---------------- init materials --------------------------------
464 public void initMaterials() {
466 // Bullets
467 stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
468 TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
469 key2.setGenerateMips(true);
470 Texture tex2 = assetManager.loadTexture(key2);
471 stone_mat.setTexture("ColorMap", tex2);
476 //---------------gestion des balles--------------------------
477 private void prepareBullet() {
479 //balles normales
480 normalbullet = new Sphere(32, 32, 0.1f, true, false);
481 normalbullet.setTextureMode(TextureMode.Projected);
482 normalbulletCollisionShape = new SphereCollisionShape(0.2f);
483 matnormalBullet = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
484 matnormalBullet.setColor("Color", ColorRGBA.DarkGray);
485 matnormalBullet.setColor("GlowColor", ColorRGBA.DarkGray);
486 getPhysicsSpace().addCollisionListener(this);
487 normalbulletgeo = new Geometry("bullet", normalbullet);
488 normalbulletgeo.setMaterial(matnormalBullet);
489 normalbulletgeo.setShadowMode(ShadowMode.CastAndReceive);
490 //rocket
491 rocketbullet = new Sphere(32, 32, 0.7f, true, false);
492 rocketbullet.setTextureMode(TextureMode.Projected);
493 rocketbulletCollisionShape = new SphereCollisionShape(0.7f);
494 matrocketBullet = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
495 matrocketBullet.setColor("Color", ColorRGBA.DarkGray);
496 matrocketBullet.setColor("GlowColor", ColorRGBA.DarkGray);
497 getPhysicsSpace().addCollisionListener(this);
498 rocketbulletgeo = new Geometry("rocket", rocketbullet);
499 rocketbulletgeo.setMaterial(matrocketBullet);
500 rocketbulletgeo.setShadowMode(ShadowMode.CastAndReceive);
505 public void makeBullet()
508 CWeapon lWeapon = me.getCurrentWeapon();
511 if ( (lWeapon != null) && (lWeapon.Shoot()) )
513 initHUD();
515 switch (lWeapon.WeaponType())
518 case CWeapon.NORMAL_WEAPON_TYPE :
520 Geometry normalb= normalbulletgeo.clone();
521 normalb.setLocalTranslation(player.getPhysicsLocation().add(cam.getDirection().mult(5)));
522 CBulletControl bulletControl = new CBulletControl(normalbulletCollisionShape, 1,1f);
523 bulletControl.setCcdMotionThreshold(0.1f);
524 bulletControl.setLinearVelocity(cam.getDirection().mult(300));
525 normalb.setName(""+me.getCurrentWeapon().getDamage());
526 normalb.addControl(bulletControl);
527 rootNode.attachChild(normalb);
528 getPhysicsSpace().add(bulletControl);
529 break;
532 case CWeapon.ROCKET_WEAPON_TYPE :
534 Geometry rocketb= rocketbulletgeo.clone();
535 rocketb.setLocalTranslation(player.getPhysicsLocation().add(cam.getDirection().mult(5)));
536 CBulletControl bulletControl = new CBulletControl(assetManager,rocketbulletCollisionShape, 1,3f,"rocket");
537 bulletControl.setCcdMotionThreshold(0.1f);
538 bulletControl.setLinearVelocity(cam.getDirection().mult(200));
539 rocketb.setName(""+me.getCurrentWeapon().getDamage());
540 rocketb.addControl(bulletControl);
541 rootNode.attachChild(rocketb);
542 getPhysicsSpace().add(bulletControl);
543 break;
546 case CWeapon.LIGHT_WEAPON_TYPE :
548 Geometry normalb= normalbulletgeo.clone();
549 normalb.setLocalTranslation(player.getPhysicsLocation().add(cam.getDirection().mult(5)));
550 CBulletControl bulletControl = new CBulletControl(assetManager,rocketbulletCollisionShape, 1,3f,"light");
551 bulletControl.setCcdMotionThreshold(0.1f);
552 bulletControl.setLinearVelocity(cam.getDirection().mult(100));
553 normalb.setName(""+me.getCurrentWeapon().getDamage());
554 normalb.addControl(bulletControl);
555 rootNode.attachChild(normalb);
556 getPhysicsSpace().add(bulletControl);
557 break;
563 private PhysicsSpace getPhysicsSpace()
565 return bulletAppState.getPhysicsSpace();
568 public void collision(PhysicsCollisionEvent event)
570 if (event.getNodeA().getName().equals(me.getName()) && event.getObjectB() instanceof CBulletControl) {
571 int damage= Integer.parseInt(event.getNodeB().getName());
572 if(me.getLife() <= damage)
574 me.setLife(1000);
575 player.setPhysicsLocation(new Vector3f(-400,100, -100));
576 initHUD();
578 }else
580 me.setLife(me.getLife()-damage);
581 initHUD();
591 * @param pPlayer
592 * @return
594 public boolean addPlayer(String name,Vector3f initposition)
596 boolean lResult = false;
598 //addplayer =new CCharacter (rootNode,assetManager,bulletAppState,initposition,name);
599 lResult = true;
600 // TODO : g�rer un nombre maxi de jouers.
601 mPlayersList.add(new CCharacter (rootNode,assetManager,bulletAppState,initposition,name));
602 initHUD();
603 return lResult;
606 // TODO : impl�menter removePlayer.
608 public void setPlayerAtPosition(
609 String pPlayerName,
610 Vector3f move, Vector3f viewdir)
612 //moveplayer = new moveplayer(pPlayerName,move,viewdir);
613 // Recherche du joueur dans la lise des joueurs.
614 int i=0;
615 while(i<mPlayersList.size() && mPlayersList.size()>0)
617 if(mPlayersList.get(i).getName().matches(pPlayerName))
619 mPlayersList.get(i).setLocalPosition(move.add(0, 0.01f, 0));
620 mPlayersList.get(i).setViewDirection(viewdir);
621 break;
622 }else
624 i++;
629 public void setPlayerShootAtPosition(
630 String pPlayerName,
631 Vector3f move, Vector3f viewdir,int weaponnumber)
633 //shootplayer = new shootplayer(pPlayerName,move,viewdir,0);
634 // Recherche du joueur dans la lise des joueurs.
635 int i=0;
636 while(i<mPlayersList.size() && mPlayersList.size()>0)
638 if(mPlayersList.get(i).getName().matches(pPlayerName))
640 mPlayersList.get(i).setLocalPosition(move.add(0, 0.01f, 0));
641 mPlayersList.get(i).setViewDirection(viewdir);
642 mPlayersList.get(i).setWeaponNumber(weaponnumber);
643 mPlayersList.get(i).isShoot=true;
644 break;
645 }else
647 i++;
652 public void setPlayerEndShoot(String pPlayerName)
654 //shootplayer = new shootplayer(pPlayerName,move,viewdir,0);
655 // Recherche du joueur dans la lise des joueurs.
656 int i=0;
657 while(i<mPlayersList.size() && mPlayersList.size()>0)
659 if(mPlayersList.get(i).getName().matches(pPlayerName))
661 mPlayersList.get(i).isShoot=false;
662 break;
663 }else
665 i++;
670 public void setPlayerSwitchLight(String pPlayerName)
672 int i=0;
673 while(i<mPlayersList.size() && mPlayersList.size()>0)
675 if(mPlayersList.get(i).getName().matches(pPlayerName))
677 mPlayersList.get(i).SwitchLight();
678 break;
679 }else
681 i++;
688 * @return
690 public float getPlayerX()
692 return player.getPhysicsLocation().clone().x;
697 * @return
699 public float getPlayerY()
701 return player.getPhysicsLocation().clone().y;
706 * @return
708 public float getPlayerZ()
710 return player.getPhysicsLocation().clone().z;
713 public Vector3f getPlayerV3f()
715 return player.getPhysicsLocation().clone();
717 public Vector3f getPlayerviewDirection()
719 return cam.getDirection().clone();