/** * this sketch illustrates how we designed the creatures 'hysteria'. * they are dangerous, very small, and live in swarms in the water. */ import gestalt.Gestalt; import gestalt.p5.GestaltPlugIn; import gestalt.shape.Mesh; import mathematik.Vector3f; import verhalten.Engine; import verhalten.Wander; import processing.opengl.*; public class Hysteria extends PApplet { private GestaltPlugIn gestalt; private HysteriaEntity[] _myEntities; private Mesh _myMesh; private float[] _myVertices; private float[] _myColor; public void setup() { /* setup p5 */ size(640, 480, OPENGL); framerate(50); rectMode(CENTER); noStroke(); gestalt = new GestaltPlugIn(this); /* g1 */ gestalt.camera().fovy = 25f; gestalt.camera().setMode(Gestalt.CAMERA_MODE_LOOK_AT); int myNumberOfEntities = 150; _myVertices = new float[myNumberOfEntities * 3]; _myColor = new float[myNumberOfEntities * 4]; /* create mesh */ _myMesh = gestalt.drawablefactory().mesh(false, _myVertices, 3, _myColor, 4, null, 2, null, Gestalt.MESH_TRIANGLES); _myMesh.material().wireframe = false; _myMesh.material().transparent = true; _myMesh.material().getColor().r = 0.75f; _myMesh.material().getColor().g = 1.0f; _myMesh.material().getColor().b = 0.1f; _myMesh.material().getColor().a = 0.05f; _myMesh.material().blendmode = Gestalt.MATERIAL_BLEND_INVERS_MULTIPLY; _myMesh.material().depthtest = false; gestalt.bin(Gestalt.BIN_3D).add(_myMesh); /* create entites */ _myEntities = new HysteriaEntity[myNumberOfEntities]; for (int i = 0; i < _myEntities.length; i++) { _myEntities[i] = new HysteriaEntity(i, _myMesh); } } public void draw() { /* clear screen */ background(50); /* change shape */ if (keyPressed) { if (key == '1') { _myMesh.setPrimitive(Gestalt.MESH_LINE_LOOP); } if (key == '2') { _myMesh.setPrimitive(Gestalt.MESH_POINTS); } if (key == '3') { _myMesh.setPrimitive(Gestalt.MESH_POLYGON); } if (key == '4') { _myMesh.setPrimitive(Gestalt.MESH_QUAD_STRIP); } if (key == '5') { _myMesh.setPrimitive(Gestalt.MESH_QUADS); } if (key == '6') { _myMesh.setPrimitive(Gestalt.MESH_TRIANGLES); } } /* update entities */ for (int i = 0; i < _myEntities.length; i++) { _myEntities[i].loop(1 / 50f); final float myOffset = random(0, 1) * 2; _myEntities[i].position().x += random(0, 1) * myOffset - myOffset / 2; _myEntities[i].position().y += random(0, 1) * myOffset - myOffset / 2; } } private class HysteriaEntity { private static final float ourConstraint = 200; private Engine _myWanderEngine; private Wander _myWander; private Mesh _myGroupView; private int _myPositionIndex; public HysteriaEntity(int thePositionIndex, Mesh theGroupView) { _myGroupView = theGroupView; _myPositionIndex = thePositionIndex; /* setup an engine */ _myWanderEngine = new Engine(); _myWanderEngine.velocity().set(10, 0, 0); /* setup behavior */ _myWander = new Wander(); _myWander.possibleDirections().z = 0; } public Vector3f position() { return _myWanderEngine.position(); } public void loop(float theDeltaTime) { /* wander */ Vector3f myArriveDirection = new Vector3f(); _myWander.get(_myWanderEngine, theDeltaTime, myArriveDirection); _myWanderEngine.apply(theDeltaTime, myArriveDirection); if (mousePressed) { _myWanderEngine.setMaximumForce(60.0f); _myWanderEngine.setMaximumSpeed(50.0f); } else { _myWanderEngine.setMaximumForce(12.0f); _myWanderEngine.setMaximumSpeed(10.0f); } /* teleport */ if (_myWanderEngine.position().length() > ourConstraint / 2) { _myWanderEngine.position().set(random(0, 1) * ourConstraint - ourConstraint / 2, random(0, 1) * ourConstraint - ourConstraint / 2, 0); } /* update arrays */ _myGroupView.vertices()[_myPositionIndex * 3 + 0] = _myWanderEngine.position().x; _myGroupView.vertices()[_myPositionIndex * 3 + 1] = _myWanderEngine.position().y; _myGroupView.vertices()[_myPositionIndex * 3 + 2] = _myWanderEngine.position().z; _myGroupView.colors()[_myPositionIndex * 4 + 0] = 0.75f; _myGroupView.colors()[_myPositionIndex * 4 + 1] = 1; _myGroupView.colors()[_myPositionIndex * 4 + 2] = 0.1f; float myDistance = _myWanderEngine.position().length() / (ourConstraint / 2); _myGroupView.colors()[_myPositionIndex * 4 + 3] = 0.25f * (1 - pow(myDistance, 0.25f)); } } public static void main(String[] args) { PApplet.main(new String[] { "Hysteria" } ); } }