Skip to content

Commit

Permalink
Fixes for running flockers in 3D.
Browse files Browse the repository at this point in the history
  • Loading branch information
TaylorMutch committed Nov 23, 2017
1 parent a6223c2 commit b27e01d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
20 changes: 20 additions & 0 deletions examples/Flockers/flockers/server3D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.modules import CanvasGrid3D

from .model import BoidModel


def boid_draw(agent):
return {"Layer": 0, "Shape": "circle", "r": 2, "Filled": "true", "Color": "red"}

boid_canvas = CanvasGrid3D(boid_draw, 100, 100, 500, 500, flip_y=True)
model_params = {
"population": 100,
"width": 100,
"height": 100,
"speed": 5,
"vision": 10,
"separation": 2
}

server = ModularServer(BoidModel, [boid_canvas], "Boids", model_params)
3 changes: 3 additions & 0 deletions examples/Flockers/run3D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from flockers.server3D import server

server.launch()
29 changes: 27 additions & 2 deletions mesa/visualization/modules/CanvasGrid3DVisualization.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from collections import defaultdict

from mesa.visualization.modules import CanvasGrid


Expand All @@ -7,12 +9,35 @@ class CanvasGrid3D(CanvasGrid):
package_includes = ["three.min.js", "OrbitControls.js", "Canvas3DModule.js"]

def __init__(self, *args, **kwargs):
self.flip_y = kwargs.pop('flip_y', False)
super().__init__(*args, **kwargs)

# Override the initialization of js_code
self.js_code = (
"elements.push ({});".format(
"new Canvas3DModule({}, {}, {}, {})".format(
self.canvas_width, self.canvas_height, self.grid_width, self.grid_height)
"new Canvas3DModule({}, {}, {}, {}, {})".format(
self.canvas_width, self.canvas_height, self.grid_width, self.grid_height,
'true' if self.flip_y else 'false'
)
)
)

def render(self, model):
if not hasattr(model, 'grid'):
if hasattr(model, 'space'):
grid_state = defaultdict(list)
for obj in model.schedule.agents:
portrayal = self.portrayal_method(obj)
x, y = obj.pos
x = ((x - model.space.x_min) /
(model.space.x_max - model.space.x_min))
y = ((y - model.space.y_min) /
(model.space.y_max - model.space.y_min))
portrayal["x"] = x * model.space.width
portrayal["y"] = y * model.space.height
grid_state[0].append(portrayal)
return grid_state
else:
return None
else:
return super().render(model)
15 changes: 11 additions & 4 deletions mesa/visualization/templates/js/Canvas3DModule.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_height) {
var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_height, flip_y) {

// TODO - determine how to allow grass patches to be grown in the base layer, instead of as cubes.
// Perhaps allow it to be determined by the portrayal method, 'cube' vs 'plane'?
Expand All @@ -11,6 +11,7 @@ var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_heig
this.bottom = grid_height / 2;
this.top = grid_height / 2 * -1;
this.offset = 0.1;
this.flip_y = flip_y;

var self = this;

Expand All @@ -34,7 +35,7 @@ var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_heig
var material = new THREE.MeshBasicMaterial({color: 'white', side: THREE.DoubleSide});
var mesh = new THREE.Mesh( colorPlane, material );
scene.add( mesh );
camera.position.z = 10;
camera.position.z = (grid_height + grid_width) / 2;

var animate = function () {
requestAnimationFrame( animate );
Expand Down Expand Up @@ -84,8 +85,12 @@ var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_heig
mesh.userData = data;
group.add(mesh);
mesh.position.copy(
new THREE.Vector3( -self.width/2 + data.x + 0.5, -self.height / 2 + data.y + .5, 0.5 + self.offset)
new THREE.Vector3( -self.width/2 + data.x, -self.height / 2 + data.y, 0.5 + self.offset)
);
if (self.flip_y) {
mesh.position.y = self.height / 2 - data.y;
}
console.log(data.x, data.y);
mesh.updateMatrix();
};

Expand Down Expand Up @@ -115,6 +120,8 @@ var Canvas3DModule = function(canvas_width, canvas_height, grid_width, grid_heig
};

this.reset = function() {
// Do nothing, the render call that occurs will cleanup as necessary.
// Reset camera position
camera.position.copy(new THREE.Vector3(0, 0, (grid_width + grid_height) / 2));
camera.matrix.needsUpdate();
}
};

0 comments on commit b27e01d

Please sign in to comment.