使用C#在DirectX中滚动滚珠

时间:2011-06-08 19:39:04

标签: c# directx 3d direct3d

我试图在形状上创建一个带有球的跷跷板,根据形状角度,球滚动。

以下是它的截图。

enter image description here

因此,跷跷板的形状基于轨迹栏值产生的角度移动。

以下是声明的变量:

private const float ONE_DEGREE = 0.0174532924f;
        private ID3DMesh tab;        
        private ID3DMesh ball;

'tab'变量是形状。

此方法设置形状的角度:

public void setShapeAngle(float degree)
{            
    tabTargetAngle = Util.DegreeToRadian(degree);
}

以下是更新它的方法:

public void Update(int elapsedTime)
        {

            if (tab.Pitch != tabTargetAngle)
            {
                if (tabTargetAngle > tab.Pitch)
                {
                    if (tab.Pitch >= (tabTargetAngle - ONE_DEGREE))
                    {
                        tab.Pitch = tabTargetAngle;

                    }
                    else
                    {
                        tab.Pitch += tabuaSpeed * elapsedTime;                        
                    }
                }
                else if (tabTargetAngle < tab.Pitch)
                {
                    if (tab.Pitch <= (tabTargetAngle + ONE_DEGREE))
                    {
                        tab.Pitch = tabTargetAngle;

                    }
                    else
                    {
                        tab.Pitch -= tabuaSpeed * elapsedTime;                        

                    }

                }

            }                                                 
        }

所有对象都是ID3DMesh对象。这是ID3DMesh类的代码。

 public interface ID3DMesh : IDisposable
    {
        Color Ambient { get; set; }
        CollisionTestMethod CollisionDetectionMethod { get; set; }
        Mesh D3DXMesh { get; }
        Color Diffuse { get; set; }
        Color Emissive { get; set; }
        Material[] Materials { get; set; }
        ID3DMesh Parent { get; set; }
        float Pitch { get; set; }
        Vector3 PivotOffset { get; set; }
        float PivotOffsetX { get; set; }
        float PivotOffsetY { get; set; }
        float PivotOffsetZ { get; set; }
        Vector3 Position { get; set; }
        RenderOptions RenderSettings { get; set; }
        float Roll { get; set; }
        Vector3 Scale { get; set; }
        float ScaleX { get; set; }
        float ScaleY { get; set; }
        float ScaleZ { get; set; }
        Color Specular { get; set; }
        float SpecularSharpness { get; set; }
        Texture[] Textures { get; set; }
        Color WireColor { get; set; }
        float X { get; set; }
        float Y { get; set; }
        float Yaw { get; set; }
        float Z { get; set; }

        MeshBoundingBox GetBoundingBox();
        MeshBoundingSphere GetBoundingSphere();
        float GetDepth();
        float GetHeight();
        float GetWidth();
        Matrix GetWorldMatrix();
        bool Intersects(ID3DMesh mesh);
        void Link(ID3DMesh parentMesh, Vector3 linkPosition);
        void Move(float xAmount, float yAmount, float zAmount);
        void Render();
        void RenderPlanarShadow(Plane groundPlane, Light light, bool allowDoubleBlending);
        void SetDepth(float depth);
        void SetDepth(float depth, bool uniformScale);
        void SetHeight(float height);
        void SetHeight(float height, bool uniformScale);
        void SetPlanarShadowOpacity(float shadowOpacity);
        void SetScale(float amount);
        void SetScale(float xAmount, float yAmount, float zAmount);
        void SetSize(float width, float height, float depth);
        void SetWidth(float width);
        void SetWidth(float width, bool uniformScale);
    }

我尝试使用Move(float,float,float)方法。但它并没有像它应该的那样移动。如果你可以帮助我。

谢谢。

2 个答案:

答案 0 :(得分:2)

(注意:下面我将忽略第三个维度,因为球将始终沿同一平面移动)

如果我们把跷跷板作为参考框架,我认为球的移动将类似于harmonic oscillator的移动。也就是说,球在给定时刻s(t)沿着跷跷板的位置将由下式给出:

  

s(t)= L cos(2πt/ T +φ)

其中L是跷跷板的长度(谐波的振幅),T是球从跷跷板的一端移动到另一端并返回到起点(谐波的周期)所需的时间。 φ,谐波的初始相位,用于调整公式,因此s(0)为您提供起始位置。如果你想让它从中心开始,你需要使s(0)= 0,这意味着你需要余弦为0.所以你必须使φ为π/ 2(90度),因为cos(π) / 2)= 0。

有了这个,你可以通过改变世界变换把球放到位。如果你将它旋转到跷跷板的当前角度(让我们称之为θ(t)),你可以通过沿xx轴的s(t)值来平移球。

这相当于将(s(t),θ(t))视为球在极坐标中的位置。然后,您可以使用以下公式在给定时间(x(t),y(t))获得笛卡尔坐标:

  

x(t)= s(t)cos(θ)

     

y(t)= s(t)sin(θ)

答案 1 :(得分:1)

(假设向上矢量为(0,1,0),标签与X轴对齐)

你可以想象球必须沿着X轴向下滚动标签,你必须计算Y位置才能让它贴在标签上。

你可以将Move()方法用于X位置,因为球的速度会以相对的方式影响它的X位置。

通过设置Y属性,可以更容易地计算每个X位置的Y位置(只要球保留在选项卡上)。

如果我是你,我首先要创建一个计算Y位置的方法,以使球“适应任何X位置的标签”。

如果这不能指向正确的方向,请详细说明“它没有动起来”。