modelviewer: rewrite camera handling to be more correct

This commit is contained in:
Adam
2016-11-27 20:08:14 -05:00
parent 5f0ce62b6b
commit 3508cd4a33
2 changed files with 262 additions and 178 deletions

View File

@@ -1,218 +1,308 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Adam <Adam@sigterm.info> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.modelviewer; package net.runelite.modelviewer;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.glRotatef; import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTranslatef; import static org.lwjgl.opengl.GL11.glTranslatef;
public class Camera { public class Camera
public static float moveSpeed = 0.05f; {
private static final float MAX_X = 89;
private static float maxLook = 85; public float moveSpeed = 0.05f;
private static float mouseSensitivity = 0.05f; private float mouseSensitivity = 0.05f;
private static Vector3f pos; private Vector3f pos = new Vector3f(0, 0, 0);
private static Vector3f rotation; private Vector3f rotation = new Vector3f(0, 0, 0);
public static void create() { public void apply()
pos = new Vector3f(0, 0, 0); {
rotation = new Vector3f(0, 0, 0); GL11.glMatrixMode(GL11.GL_MODELVIEW);
} GL11.glLoadIdentity();
public static void apply() { glRotatef(rotation.x, 1, 0, 0);
if(rotation.y / 360 > 1) { glRotatef(rotation.y, 0, 1, 0);
rotation.y -= 360; glRotatef(rotation.z, 0, 0, 1);
} else if(rotation.y / 360 < -1) { glTranslatef(-pos.x, -pos.y, -pos.z);
rotation.y += 360;
}
// glLoadIdentity();
glRotatef(rotation.x, 1, 0, 0);
glRotatef(rotation.y, 0, 1, 0);
glRotatef(rotation.z, 0, 0, 1);
glTranslatef(-pos.x, -pos.y, -pos.z);
}
public static void acceptInput(float delta) { GL11.glPopMatrix();
acceptInputRotate(delta); }
acceptInputGrab();
acceptInputMove(delta);
}
public static void acceptInputRotate(float delta) { public void acceptInput(float delta)
if(Mouse.isGrabbed()) { {
float mouseDX = Mouse.getDX(); acceptInputRotate(delta);
float mouseDY = -Mouse.getDY(); acceptInputGrab();
rotation.y += mouseDX * mouseSensitivity * delta; acceptInputMove(delta);
rotation.x += mouseDY * mouseSensitivity * delta; }
rotation.x = Math.max(-maxLook, Math.min(maxLook, rotation.x));
}
}
public static void acceptInputGrab() { public void acceptInputRotate(float delta)
if(Mouse.isInsideWindow() && Mouse.isButtonDown(0)) { {
Mouse.setGrabbed(true); if (Mouse.isGrabbed())
} {
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { float mouseDX = Mouse.getDX();
Mouse.setGrabbed(false); float mouseDY = -Mouse.getDY();
}
}
public static void acceptInputMove(float delta) { rotation.y += mouseDX * mouseSensitivity * delta;
boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_W); rotation.x += mouseDY * mouseSensitivity * delta;
boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_S);
boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_D);
boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_A);
boolean keyFast = Keyboard.isKeyDown(Keyboard.KEY_Q);
boolean keySlow = Keyboard.isKeyDown(Keyboard.KEY_E);
boolean keyFlyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
boolean keyFlyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
rotation.y %= 360.0f;
rotation.x %= 360.0f;
float speed; // bound y between (-180, 180]
if (rotation.y > 180.0f)
{
rotation.y = -360.0f + rotation.y;
}
if (rotation.y <= -180.0f)
{
rotation.y = 360.0f + rotation.y;
}
if(keyFast) { // cap x to prevent from flipping upsidedown
speed = moveSpeed * 5; if (rotation.x < -MAX_X)
} {
else if(keySlow) { rotation.x = -MAX_X;
speed = moveSpeed / 2; }
} if (rotation.x > MAX_X)
else { {
speed = moveSpeed; rotation.x = MAX_X;
} }
}
}
speed *= delta; public void acceptInputGrab()
{
if (Mouse.isInsideWindow() && Mouse.isButtonDown(0))
{
Mouse.setGrabbed(true);
}
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
{
Mouse.setGrabbed(false);
}
}
if(keyFlyUp) { public void acceptInputMove(float delta)
pos.y += speed; {
} boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_W);
if(keyFlyDown) { boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_S);
pos.y -= speed; boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_D);
} boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_A);
boolean keyFast = Keyboard.isKeyDown(Keyboard.KEY_Q);
boolean keySlow = Keyboard.isKeyDown(Keyboard.KEY_E);
boolean keyFlyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
boolean keyFlyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
if(keyDown) { float speed;
pos.x -= Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z += Math.cos(Math.toRadians(rotation.y)) * speed;
}
if(keyUp) {
pos.x += Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y)) * speed;
}
if(keyLeft) {
pos.x += Math.sin(Math.toRadians(rotation.y - 90)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y - 90)) * speed;
}
if(keyRight) {
pos.x += Math.sin(Math.toRadians(rotation.y + 90)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y + 90)) * speed;
}
}
public static void setSpeed(float speed) { if (keyFast)
moveSpeed = speed; {
} speed = moveSpeed * 5;
}
else if (keySlow)
{
speed = moveSpeed / 2;
}
else
{
speed = moveSpeed;
}
public static void setPos(Vector3f pos) { speed *= delta;
Camera.pos = pos;
}
public static Vector3f getPos() { // sin(0) = 0
return pos; // cos(0) = 1
} if (keyFlyUp)
{
pos.y += Math.cos(Math.toRadians(rotation.x)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y)) * Math.sin(Math.toRadians(rotation.x)) * speed;
pos.x += Math.sin(Math.toRadians(rotation.x)) * Math.sin(Math.toRadians(rotation.y)) * speed;
}
if (keyFlyDown)
{
pos.y -= Math.cos(Math.toRadians(rotation.x)) * speed;
pos.z += Math.cos(Math.toRadians(rotation.y)) * Math.sin(Math.toRadians(rotation.x)) * speed;
pos.x -= Math.sin(Math.toRadians(rotation.x)) * Math.sin(Math.toRadians(rotation.y)) * speed;
}
public static void setX(float x) { if (keyDown)
pos.x = x; {
} pos.x -= Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z += Math.cos(Math.toRadians(rotation.x)) * Math.cos(Math.toRadians(rotation.y)) * speed;
pos.y += Math.sin(Math.toRadians(rotation.x)) * speed;
}
if (keyUp)
{
pos.x += Math.sin(Math.toRadians(rotation.y)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.x)) * Math.cos(Math.toRadians(rotation.y)) * speed;
pos.y -= Math.sin(Math.toRadians(rotation.x)) * speed;
}
public static float getX() { if (keyLeft)
return pos.x; {
} pos.x += Math.sin(Math.toRadians(rotation.y - 90)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y - 90)) * speed;
}
if (keyRight)
{
pos.x += Math.sin(Math.toRadians(rotation.y + 90)) * speed;
pos.z -= Math.cos(Math.toRadians(rotation.y + 90)) * speed;
}
}
public static void addToX(float x) { public void setSpeed(float speed)
pos.x += x; {
} moveSpeed = speed;
}
public static void setY(float y) { public void setPos(Vector3f pos)
pos.y = y; {
} this.pos = pos;
}
public static float getY() { public Vector3f getPos()
return pos.y; {
} return pos;
}
public static void addToY(float y) { public void setX(float x)
pos.y += y; {
} pos.x = x;
}
public static void setZ(float z) { public float getX()
pos.z = z; {
} return pos.x;
}
public static float getZ() { public void addToX(float x)
return pos.z; {
} pos.x += x;
}
public static void addToZ(float z) { public void setY(float y)
pos.z += z; {
} pos.y = y;
}
public static void setRotation(Vector3f rotation) { public float getY()
Camera.rotation = rotation; {
} return pos.y;
}
public static Vector3f getRotation() { public void addToY(float y)
return rotation; {
} pos.y += y;
}
public static void setRotationX(float x) { public void setZ(float z)
rotation.x = x; {
} pos.z = z;
}
public static float getRotationX() { public float getZ()
return rotation.x; {
} return pos.z;
}
public static void addToRotationX(float x) { public void addToZ(float z)
rotation.x += x; {
} pos.z += z;
}
public static void setRotationY(float y) { public void setRotation(Vector3f rotation)
rotation.y = y; {
} this.rotation = rotation;
}
public static float getRotationY() { public Vector3f getRotation()
return rotation.y; {
} return rotation;
}
public static void addToRotationY(float y) { public void setRotationX(float x)
rotation.y += y; {
} rotation.x = x;
}
public static void setRotationZ(float z) { public float getRotationX()
rotation.z = z; {
} return rotation.x;
}
public static float getRotationZ() { public void addToRotationX(float x)
return rotation.z; {
} rotation.x += x;
}
public static void addToRotationZ(float z) { public void setRotationY(float y)
rotation.z += z; {
} rotation.y = y;
}
public static void setMaxLook(float maxLook) { public float getRotationY()
Camera.maxLook = maxLook; {
} return rotation.y;
}
public static float getMaxLook() { public void addToRotationY(float y)
return maxLook; {
} rotation.y += y;
}
public static void setMouseSensitivity(float mouseSensitivity) { public void setRotationZ(float z)
Camera.mouseSensitivity = mouseSensitivity; {
} rotation.z = z;
}
public static float getMouseSensitivity() { public float getRotationZ()
return mouseSensitivity; {
} return rotation.z;
}
public void addToRotationZ(float z)
{
rotation.z += z;
}
public void setMouseSensitivity(float mouseSensitivity)
{
this.mouseSensitivity = mouseSensitivity;
}
public float getMouseSensitivity()
{
return mouseSensitivity;
}
} }

View File

@@ -37,8 +37,6 @@ import net.runelite.cache.definitions.loaders.ModelLoader;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTranslatef;
public class ModelViewer public class ModelViewer
{ {
@@ -71,9 +69,7 @@ public class ModelViewer
long last = 0; long last = 0;
// rotate and step back to view Camera camera = new Camera();
glRotatef(-90, 1, 0, 0);
glTranslatef(0, 60.0f, 0);
while (!Display.isCloseRequested()) while (!Display.isCloseRequested())
{ {
@@ -125,10 +121,8 @@ public class ModelViewer
long delta = System.currentTimeMillis() - last; long delta = System.currentTimeMillis() - last;
last = System.currentTimeMillis(); last = System.currentTimeMillis();
Camera.create(); camera.acceptInput(delta);
Camera.acceptInput(delta); camera.apply();
Camera.apply();
} }
Display.destroy(); Display.destroy();