/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package automenta.spacenet.run.old.bio;
import automenta.spacenet.run.ArdorSpacetime;
import automenta.spacenet.run.old.graph.neural.DemoBrainz;
import automenta.spacenet.space.Repeat;
import automenta.spacenet.space.control.Zoomable;
import automenta.spacenet.space.geom.ProcessBox;
import automenta.spacenet.space.geom.physics.PhyBox;
import automenta.spacenet.space.geom.physics.PhySpaceBox;
import automenta.spacenet.var.Maths;
import automenta.spacenet.var.physical.Color;
import automenta.spacenet.var.vector.V3;
import com.ardor3d.scenegraph.Spatial;
import com.bulletphysics.dynamics.constraintsolver.Generic6DofConstraint;
import com.bulletphysics.dynamics.constraintsolver.HingeConstraint;
import com.bulletphysics.dynamics.constraintsolver.Point2PointConstraint;
import com.bulletphysics.dynamics.constraintsolver.TranslationalLimitMotor;
import com.bulletphysics.linearmath.Transform;
import javax.vecmath.Vector3f;
public class DemoSnake extends ProcessBox {
public static class PBox extends PhyBox implements Zoomable {
private PBox(V3 pos, V3 size, float mass) {
super(pos, size, mass);
color(Color.newRandomHSB(0.95, 0.5));
}
@Override
public void onZoomStart() {
}
@Override
public void onZoomStop() {
}
@Override
public boolean isZoomable() {
return true;
}
@Override
public boolean isTangible() {
return true;
}
}
/** a physical pipe of capsules */
public /*static*/ class Snake {
Vector3f tmp = new Vector3f();
public Snake(PhySpaceBox b, int numSegments, double segmentLength, double radius) {
super();
double density = 1.0;
PhyBox segment[] = new PhyBox[numSegments];
for (int s = 0; s < numSegments; s++) {
double l = segmentLength * Maths.random(0.75, 1.25);
double w = radius;
double h = radius;
float mass = (float)((l * w * h) * density);
PhyBox pb = new PBox(new V3(), new V3(l, radius, radius), mass);
b.add(pb);
segment[s] = pb;
pb.getBody().setDamping(0.05f, 0.85f);
pb.getBody().setDeactivationTime(0.8f);
pb.getBody().setSleepingThresholds(1.6f, 2.5f);
if (s > 0) {
bind(segment[s - 1], segment[s]);
}
}
}
protected void bind6DoF(PhyBox a, PhyBox b) {
final Generic6DofConstraint joint6DOF;
Transform localA = new Transform(), localB = new Transform();
boolean useLinearReferenceFrameA = false;
localA.setIdentity();
localB.setIdentity();
localA.origin.set((float) (-a.getSize().getX() / 2.0) * 1.1f, 0, 0);
localB.origin.set((float) (b.getSize().getX() / 2.0) * 1.1f, 0, 0);
joint6DOF = new Generic6DofConstraint(a.getBody(), b.getBody(), localA, localB, useLinearReferenceFrameA);
//joint6DOF.setLimit(0, -0.5f, 0.5f);
tmp.set(-3.10f, -3.1f, -3.1f);
joint6DOF.setAngularLowerLimit(tmp);
tmp.set(3.1f, 3.1f, 3.1f);
joint6DOF.setAngularUpperLimit(tmp);
phy.addConstraint(joint6DOF, false);
add(new Repeat() {
float maxStretch = 0.2f;
Vector3f pivA = new Vector3f();
Vector3f pivB = new Vector3f();
@Override protected void update(double t, double dt, Spatial parent) {
TranslationalLimitMotor m = joint6DOF.getTranslationalLimitMotor();
float xmin = m.lowerLimit.x;
xmin += (float)Maths.random(-0.01, 0.01);
float xmax = m.upperLimit.x;
xmax += (float)Maths.random(-0.01, 0.01);
xmin = Math.max(xmin, 0);
xmax = Math.min(xmax, maxStretch);
xmin = Math.min(xmin, xmax);
xmax = Math.max(xmin, xmax);
m.lowerLimit.set(xmin, 0, 0);
m.upperLimit.set(xmax, 0, 0);
// j.getPivotInA(pivA);
// j.getPivotInB(pivB);
// pivA.x += (float) Maths.random(-0.1, 0.1);
// System.out.println(j + " " + pivA + " " + pivB);
// j.setPivotA(pivA);
// j.setPivotB(pivB);
}
});
}
protected void bind(PhyBox a, PhyBox b) {
//bindPoint2Point(a, b);
//bindHinge(a, b);
bind6DoF(a, b);
}
protected void bindPoint2Point(PhyBox a, PhyBox b) {
final Point2PointConstraint j;
Vector3f pa = new Vector3f((float) (-a.getSize().getX() / 2.0) * 1.1f, 0, 0);
Vector3f pb = new Vector3f((float) (b.getSize().getX() / 2.0) * 1.1f, 0, 0);
j = new Point2PointConstraint(a.getBody(), b.getBody(), pa, pb);
//j.setLimit( -0.5f, 0.5f, 0.9f, 0.3f, 1.0f );;
phy.addConstraint(j, false);
add(new Repeat(0.01) {
Vector3f pivA = new Vector3f();
Vector3f pivB = new Vector3f();
@Override protected void update(double t, double dt, Spatial parent) {
j.getPivotInA(pivA);
j.getPivotInB(pivB);
pivA.x += (float) Maths.random(-0.1, 0.1);
System.out.println(j + " " + pivA + " " + pivB);
j.setPivotA(pivA);
j.setPivotB(pivB);
}
});
}
protected void bindHinge(PhyBox a, PhyBox b) {
HingeConstraint j;
Transform localA = new Transform(), localB = new Transform();
boolean useLinearReferenceFrameA = true;
localA.setIdentity();
localB.setIdentity();
localA.origin.set(-0.07f, 0, 0f);
localB.origin.set(0.07f, 0, 0f);
j = new HingeConstraint(a.getBody(), b.getBody(), localA, localB);
j.setLimit(-1.0f, 1.0f);
//j.setLimit( -0.5f, 0.5f, 0.9f, 0.3f, 1.0f );;
j.enableAngularMotor(true, 0.3f, 0.5f);
phy.addConstraint(j, false);
}
}
protected PhySpaceBox phy;
@Override protected void start() {
phy = add(new PhySpaceBox());
phy.physics.getTimeScale().set(1.0);
phy.physics.getGravity().set(0, -9.5, 0);
//add(phy.add(new PhyBox(new V3(1, 2, 0.5), new V3(1, 1, 1), 1.0f)));
//add(phy.add(new PhyBox(new V3(-2, 2, -0.5), new V3(1, 0.5, 1), 1.0f)));
//add(phy.add(new PhyBox(new V3(2, -2, 0.5), new V3(0.5, 1, 1), 1.0f)));
PhyBox ground = phy.add(new PhyBox(new V3(0, -2, 0), new V3(15, 0.5, 15), 0f));
ground.rotate(0.1, 0.1, 0.1);
new Snake(phy, 14, 0.35, 0.25);
add(new DemoBrainz()).scale(2).move(0,0,-0.5);
}
public static void main(String[] args) {
ArdorSpacetime.newWindow(new DemoSnake());
}
}