For this we use BallSocketJoints and RevoluteJoints. Whenever we display the simulation in realtime, the BEPUDrawer (for some reason) only wants to display BallSocketJoints, but not RevoluteJoints. Actually it doeas display it from time to time, but it's rare, and we've not been able to fix this. It should be noted we are using the development branch, we cannot test it on the release branch because of the multithreading bug.
The architecture of the program is this:
One BEPU (single-threaded) space is created for each core on the PC. Here we run the simulations in parallel, and replace the spaces when they're done simulating.
Neither the joint nor the limits can be displayed.
We are using a velocity motor in an attempt to make it behave like a joint. Could there be a better way?
EDIT:
A second issue of higher importance is that when we create these "creatures", do so randomly
Creation:
Code: Select all
foreach (var jointGene in dna.Joints)
{
var box1 = parts.Find(delegate(Entity entity) { return entity.PartNumber == jointGene.p1; });
Debug.Assert(box1 != null);
var box2 = parts.Find(delegate(Entity entity) { return entity.PartNumber == jointGene.p2; });
Debug.Assert(box2 != null);
CollisionRules.AddRule(box1,box2,CollisionRule.NoBroadPhase);
if (jointGene.type == "b")
{
var socket = new BallSocketJoint(box1, box2, (box1.Position + box2.Position)/2f);
joints.Add(socket);
}
else if (jointGene.type == "r")
{
var revolute = new RevoluteJoint(box1, box2, box1.Position, Vector3.Forward);
revolute.Limit.MinimumAngle = -MathHelper.Pi;
revolute.Limit.MaximumAngle = MathHelper.Pi;
revolute.AngularJoint.SpringSettings.StiffnessConstant = 1f;
revolute.AngularJoint.SpringSettings.DampingConstant = 100f;
if (true)
{
revolute.Motor.Settings.Mode = MotorMode.VelocityMotor;
revolute.Motor.Settings.MaximumForce = 1000;
}
else
{
revolute.Motor.Settings.Mode = MotorMode.Servomechanism;
revolute.Motor.Settings.MaximumForce = 200;
}
revolute.Limit.IsActive = true;
revolute.Motor.IsActive = true;
joints.Add(revolute);
}
}
Code: Select all
PartGene part = new PartGene();
part.id = dna.Parts.Max(p => p.id)+1;
part.type = type;
part.kfr = Math.Max(RandomFloat(), 0.1f);
part.sfr = Math.Max(RandomFloat(), 0.1f);
part.sx = RandomFloat(0.5f,6);
part.sy = RandomFloat(0.5f, 6);
part.sz = RandomFloat(0.5f, 6);
part.x = parent.x + MinOrMax(-part.sx, part.sx) * 2f;
part.y = parent.y + MinOrMax(-part.sy, part.sy) * 2;
part.z = parent.z + MinOrMax(-part.sz, part.sz) * 2;
if (part.y - part.sy < -35)
part.y += 5;
part.ox = 0;
part.oy = 0;
part.oz = 0;
part.m = Math.Max(RandomFloat(), 0.2f);
JointGene joint = new JointGene();
int maxJointID = 0;
if (dna.Joints.Count > 0)
maxJointID = dna.Joints.Max(j => j.id) + 1;
joint.id = maxJointID;
joint.p2 = part.id;
joint.p1 = parent.id;
joint.type = "r";
//Must not be the same position or the all joints will connect
//todo: The position should be between the two parts
/*joint.jx = (parent.x + part.x)/2;
joint.jy = (parent.y + part.y)/2;
joint.jz = (parent.z + part.z)/2;*/
joint.rx = 0;
joint.ry = 0;
joint.rz = 0;
joint.fmin = -2;
joint.fmax = 2;
dna.Parts.Add(part);
dna.Joints.Add(joint);