コード例 #1
0
ファイル: JointCreator.cs プロジェクト: virucho/UDDMG
        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);
            }
        }
コード例 #2
0
        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);
            }
        }