public override void ApplyPositionCorrection(float deltaTime) { if ((objA.linearVelocity - objB.linearVelocity).sqrMagnitude <= 0) { LVector2 ca = objA.GetWorldCenterOfMass(); LVector2 ra = anchorA - ca; LVector2 cb = objB.GetWorldCenterOfMass(); LVector2 rb = anchorB - cb; LFloat pa = objA.mass / (objA.mass + objB.mass); LVector3 dva = -(LVector3)normal * penetration * pa * ERP; LVector3 dvb = (LVector3)normal * penetration * (1 - pa) * ERP; LFloat dwa = LVector3.Cross(ra, dva * objA.mass).z *objA.inertiaInverse *deltaTime; LFloat dwb = LVector3.Cross(rb, dvb * objB.mass).z *objB.inertiaInverse *deltaTime; if (objA.rigidBody != null && !objA.rigidBody.isFixed) { objA.transform.position += LParser.Parse(dva); objA.transform.eulerAngles += new Vector3(0, 0, (dwa * Mathf.Rad2Deg).ToFloat()); } if (objB.rigidBody != null && !objB.rigidBody.isFixed) { objB.transform.position += LParser.Parse(dvb); objB.transform.eulerAngles += new Vector3(0, 0, (dwb * Mathf.Rad2Deg).ToFloat()); } } }
public void Run(string[] args) { // Use this for initialization LParser lparser = new LParser(); System.String[] rules = new System.String[9]; /* * rules[0] = "#define a 1"; * rules[1] = "#thickness 0.2"; * rules[2] = "#recursion 4"; * rules[3] = "#angle 22.5"; * rules[4] = @"#axiom ++++F"; * * // rules[5] = "X -> F-[[X]+X]+F[+FX]-X"; * rules[5] = @"F -> FF-[-F+F+F]+[+F-F-F]"; * rules[5] = @"F -> FF&[&F^F^F]^[^F&F&F]"; * rules[6] = @"Y -> F-F"; * */ rules[0] = "#define p 3.14"; rules[1] = "#thickness 0.2"; rules[2] = "#recursion 3"; rules[3] = "#angle 90"; rules[4] = "#axiom A"; rules[5] = "A -> B-F+CFC+F-D&F^D-F+&&CFC+F+B//"; rules[6] = "B -> A&F^CFB^F^D^^-F-D^|F^B|FC^F^A//"; rules[7] = "C -> |D^|F^B-F+C^F^A&&FA&F^C+F+B^F^D//"; rules[8] = "D -> |CFB-F+B|FA&F^A&&FB-F+B|FC//"; bool statusOK = lparser.ParseStringArray(rules); _ruleList = lparser.RunLSystem(); Console.WriteLine("RULES: " + Rules.RuleListToString(_ruleList, lparser.GlobalParameters)); Parameters currentParameters = new Parameters(); SunflowAPI sunflow = new SunflowAPI(); // SetupSunflow(sunflow); SetupSunflow(sunflow); currentParameters.roll = new Vector3(1.0f, 0.0f, 0.0f); currentParameters.pitch = new Vector3(0.0f, 1.0f, 0.0f); currentParameters.yaw = new Vector3(0.0f, 0.0f, 1.0f); currentParameters.position = new Point3(0.0f, 0.0f, 0.0f); currentParameters.primitiveType = "box"; currentParameters.length = 2.0f; currentParameters.angle = (float)lparser.Angle; currentParameters.thickness = (float)lparser.Thickness; currentParameters.localRotation = new Point3(0.0f, 0.0f, 0.0f); currentParameters.localScale = new Vector3(1.0f, currentParameters.thickness, currentParameters.thickness); currentParameters.objectCount = 0; sunflow.geometry(currentParameters.primitiveType + currentParameters.objectCount++, currentParameters.primitiveType); // Vector3 scale = new Vector3(currentParameters.length1f, currentParameters.thickness , currentParameters.thickness); currentParameters.objectCount = interpretProduction(currentParameters, _ruleList, lparser, sunflow); sunflow.render(SunflowAPI.DEFAULT_OPTIONS, new FileDisplay("lsystem.png")); return; }
private int interpretProduction(Parameters currentParameters, ArrayList production, LParser lparser, SunflowAPI sunflow) { // we start with a cube, axis in centre, we want it to behave like a line with axis at one end. // treat currentParameters.gObject as axis float moveLength; float rotation; Vector3 nvec; Matrix4 rotateMatrix; for (int i = 0; i < production.Count; i++) { Rule rule = (Rule)production[i]; // Console.WriteLine("rule: " + rule); // Console.WriteLine("Switch Type: " + rule.Type); switch (rule.Type) { case Rule.TypeEnum.Letter: // Console.WriteLine("Switch Value: " + rule.Value[0]); switch (rule.Value[0]) { case 'F': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; moveLength = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (moveLength <= 0) { moveLength = currentParameters.length; } } else { moveLength = currentParameters.length; } // Console.WriteLine("moveLength: " + moveLength); //sunflow.geometry("sphere" + currentParameters.objectCount, "sphere"); //sunflow.parameter("shaders", "sps"); // sunflow.parameter("transform", Matrix4.translation(currentParameters.position.x, // currentParameters.position.y, // currentParameters.position.z).multiply(Matrix4.scale(currentParameters.thickness * 1.1f))); //sunflow.instance("sphere" + currentParameters.objectCount + ".instance", "sphere" + currentParameters.objectCount); //currentParameters.objectCount++; nvec = currentParameters.roll.mul(moveLength * 0.5f); // axis that we roll on is the forward vector currentParameters.position.x += nvec.x; currentParameters.position.y += nvec.y; currentParameters.position.z += nvec.z; AddNewObject(sunflow, currentParameters); currentParameters.objectCount++; currentParameters.position.x += nvec.x; currentParameters.position.y += nvec.y; currentParameters.position.z += nvec.z; break; case 'f': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; moveLength = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (moveLength <= 0) { moveLength = currentParameters.length; } } else { moveLength = currentParameters.length; } nvec = currentParameters.roll.mul(moveLength * 0.5f); // axis that we roll on is the forward vector currentParameters.position.x += nvec.x; currentParameters.position.y += nvec.y; currentParameters.position.z += nvec.z; break; case '+': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } // yawing so rotate pitch and roll against the yaw vector rotateMatrix = Matrix4.rotate(currentParameters.yaw.x, currentParameters.yaw.y, currentParameters.yaw.z, rotation * d2r); currentParameters.pitch = rotateMatrix.transformV(currentParameters.pitch); currentParameters.roll = rotateMatrix.transformV(currentParameters.roll); // currentParameters.localRotation.z += rotation; break; case '-': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } // yawing so rotate pitch and roll against the yaw vector rotateMatrix = Matrix4.rotate(currentParameters.yaw.x, currentParameters.yaw.y, currentParameters.yaw.z, -rotation * d2r); currentParameters.pitch = rotateMatrix.transformV(currentParameters.pitch); currentParameters.roll = rotateMatrix.transformV(currentParameters.roll); // currentParameters.localRotation.z -= rotation; break; case '\\': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } // rolling so rotate pitch and yaw against the row vector rotateMatrix = Matrix4.rotate(currentParameters.roll.x, currentParameters.roll.y, currentParameters.roll.z, rotation * d2r); currentParameters.pitch = rotateMatrix.transformV(currentParameters.pitch); currentParameters.yaw = rotateMatrix.transformV(currentParameters.yaw); break; case '/': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } rotateMatrix = Matrix4.rotate(currentParameters.roll.x, currentParameters.roll.y, currentParameters.roll.z, -rotation * d2r); currentParameters.pitch = rotateMatrix.transformV(currentParameters.pitch); currentParameters.yaw = rotateMatrix.transformV(currentParameters.yaw); break; case '&': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } // pitching so rotate yaw and roll against the pitch vector rotateMatrix = Matrix4.rotate(currentParameters.pitch.x, currentParameters.pitch.y, currentParameters.pitch.z, rotation * d2r); currentParameters.yaw = rotateMatrix.transformV(currentParameters.yaw); currentParameters.roll = rotateMatrix.transformV(currentParameters.roll); break; case '^': if (i + 1 < production.Count && ((Rule)production[i + 1]).Type == Rule.TypeEnum.Expression) { Stack expression = (Stack)((Rule)production[i + 1]).Expression; rotation = (float)ExpressionEvaluator.EvaluateStack(expression, null, lparser.GlobalParameters); if (rotation <= 0) { rotation = currentParameters.angle; } } else { rotation = currentParameters.angle; } rotateMatrix = Matrix4.rotate(currentParameters.pitch.x, currentParameters.pitch.y, currentParameters.pitch.z, -rotation * d2r); currentParameters.yaw = rotateMatrix.transformV(currentParameters.yaw); currentParameters.roll = rotateMatrix.transformV(currentParameters.roll); break; case '|': rotateMatrix = Matrix4.rotate(currentParameters.yaw.x, currentParameters.yaw.y, currentParameters.yaw.z, 180.0f * d2r); currentParameters.pitch = rotateMatrix.transformV(currentParameters.pitch); currentParameters.roll = rotateMatrix.transformV(currentParameters.roll); break; } break; case Rule.TypeEnum.BranchStart: Parameters tmp = new Parameters(); tmp.roll = new Vector3(currentParameters.roll); tmp.pitch = new Vector3(currentParameters.pitch); tmp.yaw = new Vector3(currentParameters.yaw); tmp.position = new Point3(currentParameters.position); tmp.localRotation = new Point3(currentParameters.localRotation); tmp.localScale = new Vector3(currentParameters.localScale); tmp.angle = currentParameters.angle; tmp.length = currentParameters.length; tmp.thickness = currentParameters.thickness; tmp.primitiveType = currentParameters.primitiveType; tmp.objectCount = currentParameters.objectCount; currentParameters.objectCount = interpretProduction(tmp, rule.Branch, lparser, sunflow); break; case Rule.TypeEnum.BranchEnd: break; } } return(currentParameters.objectCount); }
public LVector2 GetWorldCenterOfMass() { return(transform.TransformPoint(LParser.Parse(mCenterOfMass))); }
public LVector2 GetWorldCenterOfMass() { return(rigidBody != null?rigidBody.GetWorldCenterOfMass() : (LVector2)LParser.Parse(transform.position)); }