メニュー 閉じる

024. p5.jsで自律エージェントの動き3D版の改良

021の改良版です。空間上をBOXエージェントが動いていて、ライトの設定もしました。マウスの動きで視点が変わり、クリックでエージェントの動きが変わります。

http://www.velvet-number.com/p5_test/test017/

var debug;

var flowfield;

var vehicles;

function setup () {

	pixelDensity (displayDensity ());
	createCanvas (windowWidth, windowHeight, WEBGL);
	background (0);
	colorMode (HSB, 100);

	flowfield = new FlowField (40);
	flowfield.init ();
	vehicles = [];

	translate (width / 2.0, height / 2.0, 0.0);

	for (var i = 0; i < 3000; i++) {
		vehicles.push (new Vehicle (new p5.Vector (random (-width / 2.0, width / 2.0), random (-height / 2.0, height / 2.0), 0.0), random (2.0, 10.0), random (0.1, 0.5)));
	}

	debug = false;

}

function draw () {

	background (0);

	ambientLight (0, 0, 10);
	pointLight (0, 0, 80, -400.0, 0.0, 0.0);
  	pointLight (0, 0, 80, 400.0, 0.0, 0.0);
  	pointLight (0, 0, 80, 0.0, -400.0, 0.0);
  	pointLight (0, 0, 80, 0.0, 400.0, 0.0);
  	pointLight (0, 0, 80, 0.0, 0.0, -400.0);
  	pointLight (0, 0, 80, 0.0, 0.0, 400.0);

	camera (0.0, 0.0, -400.0,
			0.0, 0.0, 0.0,
			0.0, 1.0, 0.0);

	rotateX (map (mouseY, 0.0, height, 0.0, PI));
	rotateZ (map (mouseX, 0.0, width, -PI, PI));

	if (debug) {
		flowfield.render ();
	}

	for (var i = 0; i < vehicles.length; i++) {
		vehicles[i].follow (flowfield);
		vehicles[i].run ();
	}

}

function keyPressed () {

	if (key == ' ') {
		debug = !debug;
	}

}

function mousePressed () {

	flowfield.init ();
	
}
function Vehicle (l, ms, mf) {

	var location = l.copy ();
	var velocity = new p5.Vector (0.0, 0.0);
	var acceleration = new p5.Vector (0.0, 0.0);

	var r = 1.0;
	var maxforce = mf;
	var maxspeed = ms;
	var theta;

	this.run = function () {
		this.update ();
		this.border ()
		this.render ();
	}

	this.update = function () {

		velocity.add (acceleration);
		velocity.limit (maxspeed);
		location.add (velocity);
		acceleration.mult (0.0);

	}

	this.border = function () {

		if (location.x < -width / 2.0 -r) {
			location.x = width / 2.0 + r;
		}
		if (location.y < -height / 2.0 -r) {
			location.y = height / 2.0 + r;
		}
		if (location.x > width / 2.0 + r) {
			location.x = -width / 2.0 - r;
		}
		if (location.y > height / 2.0 + r) {
			location.y = -height / 2.0 - r;
		}

	}

	this.render = function () {

		theta = velocity.heading () + PI / 2.0;

		noStroke ();
		push ();
		translate (location.x, location.y, 0.0);
		specularMaterial (map (theta, -1.0, 5.0, 0.0, 100.0), 100, 100);
		box (r);
		pop ();

	}

	this.applyForce = function (force) {

		acceleration.add (force);

	}

	this.follow = function (flow) {

		var desired = flow.lookup (location);
		desired.mult (maxspeed);

		var steer = p5.Vector.sub (desired, velocity);
		steer.limit (maxforce);

		this.applyForce (steer);

	}

}
function FlowField (r) {

	var field = [];

	var resolution = r;
	var cols = int (width / resolution);
	var rows = int (height / resolution);

	this.init = function () {

		noiseSeed (int (random (10000.0)));

		var xoff = 0.0;
		for (var i = 0; i < cols; i++) {
			var yoff = 0.0;
			field[i] = [];
			for (var j = 0; j < rows; j++) {
				var theta = map (noise (xoff, yoff), 0.0, 1.0, -TWO_PI, TWO_PI);
				field[i][j] = new p5.Vector (cos (theta), sin (theta), 0.0);
				yoff += 0.1;
			}
			xoff += 0.1;
		}

	}

	this.render = function () {

		for (var i = 0; i < cols; i++) {
			for (var j = 0; j < rows; j++) {
				this.draw_vector (field[i][j], i * resolution - (width / 2.0), j * resolution - (height / 2.0), resolution);
			}
		}

	}

	this.draw_vector = function (v, x, y, sc) {

		stroke (100, 50);

		var len = v.mag () * sc;

		stroke (50);
		strokeWeight (0.1);

		push ();
		translate (x, y, 0.0);
		rotateZ (v.heading ());
		line (0.0, 0.0, 0.0, len, 0.0, 0.0);
		pop ();

	}

	this.lookup = function (look_v) {

		var col = int (constrain (look_v.x / resolution, 0, cols - 1));
		var row = int (constrain (look_v.y / resolution, 0, rows - 1));
		return (field[col][row].copy ());

	}

}

 

 

Posted in p5.js , processing