public static void AddRollingBeats(Scene scene, TransformNode parentTrans) { Vector3 size = new Vector3(10.0f, 0.25f, 0.25f); Vector3 location = new Vector3(0, 3, 3); GeometryNode bar; // ////////////////////////////////////////////////////////////////// // // Create a bar and attach it to the world with a hinge with limits // // ////////////////////////////////////////////////////////////////// { TransformNode pileTrans = new TransformNode(); pileTrans.Translation = location; pileTrans.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.PiOver2); Material barMat = new Material(); barMat.Diffuse = Color.Purple.ToVector4(); barMat.Specular = Color.White.ToVector4(); barMat.SpecularPower = 10; bar = new GeometryNode("Bar"); bar.Model = new Cylinder(size.Y, size.Y, size.X, 20); bar.Material = barMat; bar.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; bar.AddToPhysicsEngine = true; bar.Physics.Interactable = true; bar.Physics.Collidable = true; bar.Physics.Shape = ShapeType.Cylinder; bar.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(bar); Vector3 pivot = location + parentTrans.Translation; Vector3 pin = Vector3.UnitY; pivot.X -= size.X * 0.5f; HingeJoint joint = new HingeJoint(pivot, pin); joint.NewtonHingeCallback = doubleDoor; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(bar.Physics, null, joint); } // ///////////////////////////////////////////////////////////////// // // Add a sliding visualObject with limits // //////////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X += size.X * 0.25f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.Red.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Slider"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin = Vector3.UnitX; sliderLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f); sliderLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f); SliderJoint joint = new SliderJoint(pivot, pin); sliderUpdate = delegate(IntPtr slider, ref Newton.NewtonHingeSliderUpdateDesc desc) { float distance = Newton.NewtonSliderGetJointPosit(slider); if (distance < sliderLimit.X) { // if the distance is smaller than the predefine interval, stop the slider desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.X); return 1; } else if (distance > sliderLimit.Y) { // if the distance is larger than the predefine interval, stop the slider desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.Y); return 1; } // no action need it if the joint angle is with the limits return 0; }; joint.NewtonSliderCallback = sliderUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } // ///////////////////////////////////////////////////////////////// // // Add a corkscrew visualObject with limits // // ///////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X -= size.X * 0.25f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.YellowGreen.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Corkscrew"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin = Vector3.UnitX; corkscrewLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f); corkscrewLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f); CorkscrewJoint joint = new CorkscrewJoint(pivot, pin); corkscrewUpdate = delegate(IntPtr corkscrew, Newton.NewtonHingeSliderUpdateDesc[] desc) { // no action need it if the joint angle is with the limits uint retCode = 0; float distance = Newton.NewtonCorkscrewGetJointPosit(corkscrew); // The first entry in NewtonHingeSliderUpdateDesc control the screw linear acceleration if (distance < corkscrewLimit.X) { // if the distance is smaller than the predefine interval, stop the slider desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew, ref desc[0], corkscrewLimit.X); retCode |= 1; } else if (distance > corkscrewLimit.Y) { // if the distance is larger than the predefine interval, stop the slider desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew, ref desc[0], corkscrewLimit.Y); retCode |= 1; } // The second entry in NewtonHingeSliderUpdateDesc control the screw angular acceleration. // Make s small screw motor by setting the angular acceleration of the screw axis // We are not going to limit the angular rotation of the screw, but is we did we should // or return code with 2 float omega = Newton.NewtonCorkscrewGetJointOmega(corkscrew); desc[1].m_Accel = 1.5f - 0.2f * omega; // or with 0x10 to tell newton this axis is active retCode |= 2; // return the code return retCode; }; joint.NewtonCorkscrewCallback = corkscrewUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } // ///////////////////////////////////////////////////////////////// // // Add a universal joint visualObject with limits // // ///////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X -= size.X * 0.45f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.YellowGreen.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Universal"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin0 = Vector3.UnitX; Vector3 pin1 = Vector3.UnitY; universalLimit.X = -30.0f * MathHelper.Pi / 180.0f; universalLimit.Y = 30.0f * MathHelper.Pi / 180.0f; UniversalJoint joint = new UniversalJoint(pivot, pin0, pin1); universalUpdate = delegate(IntPtr universal, Newton.NewtonHingeSliderUpdateDesc[] desc) { // no action need it if the joint angle is with the limits uint retCode = 0; float omega = Newton.NewtonUniversalGetJointOmega0(universal); desc[0].m_Accel = -1.5f - 0.2f * omega; retCode |= 1; float angle = Newton.NewtonUniversalGetJointAngle1(universal); if (angle < universalLimit.X) { desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1], universalLimit.X); retCode |= 2; } else if (angle > universalLimit.Y) { desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1], universalLimit.Y); retCode |= 2; } // return the code return retCode; }; joint.NewtonUniversalCallback = universalUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } }
public static void AddRollingBeats(Scene scene, TransformNode parentTrans) { Vector3 size = new Vector3(10.0f, 0.25f, 0.25f); Vector3 location = new Vector3(0, 3, 3); GeometryNode bar; // ////////////////////////////////////////////////////////////////// // // Create a bar and attach it to the world with a hinge with limits // // ////////////////////////////////////////////////////////////////// { TransformNode pileTrans = new TransformNode(); pileTrans.Translation = location; pileTrans.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.PiOver2); Material barMat = new Material(); barMat.Diffuse = Color.Purple.ToVector4(); barMat.Specular = Color.White.ToVector4(); barMat.SpecularPower = 10; bar = new GeometryNode("Bar"); bar.Model = new Cylinder(size.Y, size.Y, size.X, 20); bar.Material = barMat; bar.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; bar.AddToPhysicsEngine = true; bar.Physics.Interactable = true; bar.Physics.Collidable = true; bar.Physics.Shape = ShapeType.Cylinder; bar.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(bar); Vector3 pivot = location + parentTrans.Translation; Vector3 pin = Vector3.UnitY; pivot.X -= size.X * 0.5f; HingeJoint joint = new HingeJoint(pivot, pin); joint.NewtonHingeCallback = doubleDoor; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(bar.Physics, null, joint); } // ///////////////////////////////////////////////////////////////// // // Add a sliding visualObject with limits // //////////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X += size.X * 0.25f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.Red.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Slider"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin = Vector3.UnitX; sliderLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f); sliderLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f); SliderJoint joint = new SliderJoint(pivot, pin); sliderUpdate = delegate(IntPtr slider, ref Newton.NewtonHingeSliderUpdateDesc desc) { float distance = Newton.NewtonSliderGetJointPosit(slider); if (distance < sliderLimit.X) { // if the distance is smaller than the predefine interval, stop the slider desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.X); return(1); } else if (distance > sliderLimit.Y) { // if the distance is larger than the predefine interval, stop the slider desc.m_Accel = Newton.NewtonSliderCalculateStopAccel(slider, ref desc, sliderLimit.Y); return(1); } // no action need it if the joint angle is with the limits return(0); }; joint.NewtonSliderCallback = sliderUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } // ///////////////////////////////////////////////////////////////// // // Add a corkscrew visualObject with limits // // ///////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X -= size.X * 0.25f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.YellowGreen.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Corkscrew"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin = Vector3.UnitX; corkscrewLimit.X = ((location.X - beatLocation.X) - size.X * 0.5f); corkscrewLimit.Y = ((location.X - beatLocation.X) + size.X * 0.5f); CorkscrewJoint joint = new CorkscrewJoint(pivot, pin); corkscrewUpdate = delegate(IntPtr corkscrew, Newton.NewtonHingeSliderUpdateDesc[] desc) { // no action need it if the joint angle is with the limits uint retCode = 0; float distance = Newton.NewtonCorkscrewGetJointPosit(corkscrew); // The first entry in NewtonHingeSliderUpdateDesc control the screw linear acceleration if (distance < corkscrewLimit.X) { // if the distance is smaller than the predefine interval, stop the slider desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew, ref desc[0], corkscrewLimit.X); retCode |= 1; } else if (distance > corkscrewLimit.Y) { // if the distance is larger than the predefine interval, stop the slider desc[0].m_Accel = Newton.NewtonCorkscrewCalculateStopAccel(corkscrew, ref desc[0], corkscrewLimit.Y); retCode |= 1; } // The second entry in NewtonHingeSliderUpdateDesc control the screw angular acceleration. // Make s small screw motor by setting the angular acceleration of the screw axis // We are not going to limit the angular rotation of the screw, but is we did we should // or return code with 2 float omega = Newton.NewtonCorkscrewGetJointOmega(corkscrew); desc[1].m_Accel = 1.5f - 0.2f * omega; // or with 0x10 to tell newton this axis is active retCode |= 2; // return the code return(retCode); }; joint.NewtonCorkscrewCallback = corkscrewUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } // ///////////////////////////////////////////////////////////////// // // Add a universal joint visualObject with limits // // ///////////////////////////////////////////////////////////////// { Vector3 beatLocation = location; Vector3 beatSize = new Vector3(0.5f, 2.0f, 2.0f); beatLocation.X -= size.X * 0.45f; TransformNode pileTrans = new TransformNode(); pileTrans.Translation = beatLocation; Material beatMat = new Material(); beatMat.Diffuse = Color.YellowGreen.ToVector4(); beatMat.Specular = Color.White.ToVector4(); beatMat.SpecularPower = 10; GeometryNode beat = new GeometryNode("Beat Universal"); beat.Model = new Box(beatSize); beat.Material = beatMat; beat.Model.ShadowAttribute = ShadowAttribute.ReceiveCast; beat.AddToPhysicsEngine = true; beat.Physics.Interactable = true; beat.Physics.Collidable = true; beat.Physics.Shape = ShapeType.Box; beat.Physics.Mass = 2.0f; parentTrans.AddChild(pileTrans); pileTrans.AddChild(beat); Vector3 pivot = beatLocation + parentTrans.Translation; Vector3 pin0 = Vector3.UnitX; Vector3 pin1 = Vector3.UnitY; universalLimit.X = -30.0f * MathHelper.Pi / 180.0f; universalLimit.Y = 30.0f * MathHelper.Pi / 180.0f; UniversalJoint joint = new UniversalJoint(pivot, pin0, pin1); universalUpdate = delegate(IntPtr universal, Newton.NewtonHingeSliderUpdateDesc[] desc) { // no action need it if the joint angle is with the limits uint retCode = 0; float omega = Newton.NewtonUniversalGetJointOmega0(universal); desc[0].m_Accel = -1.5f - 0.2f * omega; retCode |= 1; float angle = Newton.NewtonUniversalGetJointAngle1(universal); if (angle < universalLimit.X) { desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1], universalLimit.X); retCode |= 2; } else if (angle > universalLimit.Y) { desc[1].m_Accel = Newton.NewtonUniversalCalculateStopAlpha1(universal, ref desc[1], universalLimit.Y); retCode |= 2; } // return the code return(retCode); }; joint.NewtonUniversalCallback = universalUpdate; ((NewtonPhysics)scene.PhysicsEngine).CreateJoint(beat.Physics, bar.Physics, joint); } }