Skip to content

Instantly share code, notes, and snippets.

@darkwave
Last active August 29, 2015 14:08
Show Gist options
  • Save darkwave/02c1174126cc353aecc5 to your computer and use it in GitHub Desktop.
Save darkwave/02c1174126cc353aecc5 to your computer and use it in GitHub Desktop.
Simple 3D engine under GPL v3
import remixlab.proscene.*;
import remixlab.dandelion.geom.Quat;
import remixlab.dandelion.core.InteractiveFrame;
import remixlab.dandelion.geom.Vec;
HashMap<String, PShape> cachedShapes = new HashMap<String, PShape>();
class Game extends Scene {
boolean keyboardEnabled = true;
boolean mouseEnabled = true;
boolean fpsEnabled = false;
boolean useLights = false;
boolean visualHintsEnabled = true;
ArrayList<Element> elements = new ArrayList<Element>();
public Game(PApplet p) {
super(p);
}
public void init() {
this.camera().setSceneRadius(120);
this.camera().lookAt(new Vec(0, 0, 0));
this.camera().setUpVector(new Vec(0, 0.5, -0.5));
this.camera().showEntireScene();
this.camera().setSceneRadius(100);
}
public void toggleHints() {
if (visualHintsEnabled) {
setVisualHints(0);
} else {
setVisualHints(Scene.AXES | Scene.GRID | Scene.PICKING );
}
visualHintsEnabled = !visualHintsEnabled;
}
public void toggleFirstPerson() {
if (fpsEnabled) {
setMouseAsFirstPerson();
} else {
setMouseAsArcball();
}
fpsEnabled = !fpsEnabled;
}
public void toggleKeyboard() {
if (keyboardEnabled)
disableKeyboardAgent();
else
enableKeyboardAgent();
keyboardEnabled = !keyboardEnabled;
}
public void toggleMouse() {
if (mouseEnabled)
disableMotionAgent();
else
enableMotionAgent();
mouseEnabled = !mouseEnabled;
}
public boolean isKeyboardEnabled() {
return keyboardEnabled;
}
public void toggleLights() {
useLights = !useLights;
}
public boolean isUsingLights() {
return useLights;
}
public void proscenium() {
background(0);
if (useLights)
lights();
else
noLights();
for (Element element : elements) {
element.display();
}
for (int i = elements.size () - 1; i >= 0; i--) {
Element element = elements.get(i);
if (element.dead) {
element.iFrame.removeFromAgentPool(motionAgent());
element.iFrame.removeFromAgentPool(keyboardAgent());
elements.remove(element);
element = null;
}
}
}
public Element addElement(String filename) {
Element element = new Element(filename);
element.iFrame = new InteractiveFrame(this);
element.iFrame.setOrientation(new Quat(radians(90), 0, 0));
element.parentGame = this;
elements.add(element);
return element;
}
public void removeElement(Element element) {
elements.remove(element);
}
public void load(String filename) {
JSONObject json = loadJSONObject(filename);
println(json);
}
public void save(String filename) {
JSONObject json = new JSONObject();
int counter = 0;
for (Element element : elements)
json.setJSONObject("element_" + counter++, element.getJSON());
saveJSONObject(json, filename);
}
public void rotate(float roll, float pitch, float yaw) {
this.camera().frame().rotate(new remixlab.dandelion.geom.Quat(radians(roll), radians(pitch), radians(yaw)));
}
}
class Element {
PShape forma;
Game parentGame;
InteractiveFrame iFrame;
String filename;
boolean dead = false;
Element(String filename) {
if (cachedShapes.containsKey(filename)) {
forma = cachedShapes.get(filename);
} else {
forma = loadShape(filename);
cachedShapes.put(filename, forma);
println("added");
}
this.filename = filename;
}
public JSONObject getJSON() {
JSONObject json = new JSONObject();
JSONObject position = new JSONObject();
position.setFloat("x", iFrame.position().x());
position.setFloat("y", iFrame.position().y());
position.setFloat("z", iFrame.position().z());
json.setJSONObject("position", position);
JSONObject rotation = new JSONObject();
Vec orientation = ((Quat) iFrame.orientation()).eulerAngles();
rotation.setFloat("roll", degrees(orientation.x()));
rotation.setFloat("pitch", degrees(orientation.y()));
rotation.setFloat("yaw", degrees(orientation.z()));
json.setJSONObject("rotation", rotation);
json.setFloat("scale", iFrame.magnitude());
json.setString("filename", filename);
//println(json);
return json;
}
Element rotate(float roll, float pitch, float yaw) {
iFrame.rotate(new remixlab.dandelion.geom.Quat(radians(roll), radians(pitch), radians(yaw)));
return this;
}
Element setTexture(String filename) {
forma.setTexture(loadImage(filename));
return this;
}
Element setScale(float scale) {
iFrame.setMagnitude(scale);
return this;
}
float getX() {
return iFrame.position().x();
}
float getY() {
return iFrame.position().y();
}
float getZ() {
return iFrame.position().z();
}
Element setX(float x) {
return setPosition(x, iFrame.position().y(), iFrame.position().z());
}
Element setY(float y) {
return setPosition(iFrame.position().x(), y, iFrame.position().z());
}
Element setZ(float z) {
return setPosition(iFrame.position().x(), iFrame.position().y(), z);
}
Element move(float x, float y, float z) {
return setPosition(iFrame.position().x() + x, iFrame.position().y() + y, iFrame.position().z() + z);
}
Element setPosition(float x, float y) {
return setPosition(x, y, iFrame.position().z());
}
Element setPosition(float x, float y, float z) {
iFrame.setPosition(x, y, z);
return this;
}
void display(PGraphics pg) {
if (!visible)
return;
pg.pushMatrix();
iFrame.applyTransformation();
pg.shape(forma);
pg.popMatrix();
}
boolean visible = true;
void hide() {
visible = false;
}
void show() {
visible = true;
}
void display() {
display(g);
}
boolean mouseOver() {
return (parentGame != null && iFrame.grabsInput(parentGame.motionAgent()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment