Ограничивающие сферы движутся дальше, чем сферический объект - PullRequest
1 голос
/ 14 марта 2012

У меня есть программа, которую я делаю с другими, и я столкнулся с проблемой.Я работаю над добавлением моделей полигонов в нашу сцену в окне XNA.У меня есть эта часть завершена.У меня также есть ограничивающие сферы (я знаю, что я помечен как ограничивающий прямоугольник, но нет ограничивающей сферы), рисующий вокруг каждого многоугольника.Моя проблема в том, что когда я перемещаю многоугольники вокруг трехмерного пространства, ограничивающие сферы двигаются вдвое больше, чем многоугольники.Я представляю, что это нечто внутри моих полигональных матриц, которые я использую для создания ограничивающей сферы, которая заставляет ее двигаться в два раза больше, но это только предположение.Просто чтобы прояснить, я приведу пример моей проблемы.Если я удерживаю D, чтобы переместить многоугольник вдоль оси X.(model.position.X--;) Многоугольник перемещается, как ожидается, но ограничивающая сфера вокруг многоугольника перемещается в два раза больше.Спасибо за помощь, ребята!

Вот как я рисую модели и ограничивающие сферы:

       public void Draw(Matrix view, Matrix projection, bool drawBoundingSphere)
    {
        Matrix translateMatrix = Matrix.CreateTranslation(position);
        Matrix worldMatrix = translateMatrix * Matrix.CreateScale(scaleRatio);

        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (BasicEffect effect in mesh.Effects)
            {
                effect.World = worldMatrix * modelAbsoluteBoneTransforms[mesh.ParentBone.Index];
                effect.View = view;
                effect.Projection = projection;
                effect.EnableDefaultLighting();
                effect.PreferPerPixelLighting = true;
            }
            mesh.Draw();
            if (drawBoundingSphere)
            {
                // the mesh's BoundingSphere is stored relative to the mesh itself.
                // (Mesh space). We want to get this BoundingSphere in terms of world
                // coordinates. To do this, we calculate a matrix that will transform
                // from coordinates from mesh space into world space....
                Matrix world = modelAbsoluteBoneTransforms[mesh.ParentBone.Index] * worldMatrix;
                // ... and then transform the BoundingSphere using that matrix.
                BoundingSphere sphere = BoundingSphereRenderer.TransformBoundingSphere(mesh.BoundingSphere, world);
                // now draw the sphere with our renderer
                BoundingSphereRenderer.Draw(sphere, view, projection);
            }
        } 

А вот код BoundingSphereRenderer:

        private static VertexBuffer vertexBuffer;
    private static BasicEffect effect;
    private static int lineCount;
    public static void Initialize(GraphicsDevice graphicsDevice, int sphereResolution)
    {
        // create our effect
        effect = new BasicEffect(graphicsDevice);
        effect.LightingEnabled = false;
        effect.VertexColorEnabled = true;
        // calculate the number of lines to draw for all circles
        lineCount = (sphereResolution + 1) * 3;
        // we need two vertices per line, so we can allocate our vertices
        VertexPositionColor[] vertices = new VertexPositionColor[lineCount * 2];
        // compute our step around each circle
        float step = MathHelper.TwoPi / sphereResolution;
        // used to track the index into our vertex array
        int index = 0;
        //create the loop on the XY plane first
        for (float angle = 0f; angle < MathHelper.TwoPi; angle += step)
        {
            vertices[index++] = new VertexPositionColor(new Vector3((float)Math.Cos(angle), (float)Math.Sin(angle), 0f), Color.Blue);
            vertices[index++] = new VertexPositionColor(new Vector3((float)Math.Cos(angle + step), (float)Math.Sin(angle + step), 0f), Color.Blue);
        }
        //next on the XZ plane
        for (float angle = 0f; angle < MathHelper.TwoPi; angle += step)
        {
            vertices[index++] = new VertexPositionColor(new Vector3((float)Math.Cos(angle), 0f, (float)Math.Sin(angle)), Color.Red);
            vertices[index++] = new VertexPositionColor(new Vector3((float)Math.Cos(angle + step), 0f, (float)Math.Sin(angle + step)), Color.Red);
        }
        //finally on the YZ plane
        for (float angle = 0f; angle < MathHelper.TwoPi; angle += step)
        {
            vertices[index++] = new VertexPositionColor(new Vector3(0f, (float)Math.Cos(angle), (float)Math.Sin(angle)), Color.Green);
            vertices[index++] = new VertexPositionColor(new Vector3(0f, (float)Math.Cos(angle + step), (float)Math.Sin(angle + step)), Color.Green);
        }
        // now we create the vertex buffer and put the vertices in it
        vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly);
        vertexBuffer.SetData(vertices);
    }

    public static void Draw(this BoundingSphere sphere, Matrix view, Matrix projection)
    {
        if (effect == null)
            throw new InvalidOperationException("You must call Initialize before you can render any spheres.");
        // set the vertex buffer
        effect.GraphicsDevice.SetVertexBuffer(vertexBuffer);
        // update our effect matrices
        effect.World = Matrix.CreateScale(sphere.Radius) * Matrix.CreateTranslation(sphere.Center);
        effect.View = view;
        effect.Projection = projection;
        // draw the primitives with our effect
        effect.CurrentTechnique.Passes[0].Apply();
        effect.GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, lineCount);
    }

    public static BoundingSphere TransformBoundingSphere(BoundingSphere sphere, Matrix transform)
    {
        BoundingSphere transformedSphere;
        // the transform can contain different scales on the x, y, and z components.
        // this has the effect of stretching and squishing our bounding sphere along
        // different axes. Obviously, this is no good: a bounding sphere has to be a
        // SPHERE. so, the transformed sphere's radius must be the maximum of the 
        // scaled x, y, and z radii.
        // to calculate how the transform matrix will affect the x, y, and z
        // components of the sphere, we'll create a vector3 with x y and z equal
        // to the sphere's radius...
        Vector3 scale3 = new Vector3(sphere.Radius, sphere.Radius, sphere.Radius);
        // then transform that vector using the transform matrix. we use
        // TransformNormal because we don't want to take translation into account.
        scale3 = Vector3.TransformNormal(scale3, transform);
        // scale3 contains the x, y, and z radii of a squished and stretched sphere.
        // we'll set the finished sphere's radius to the maximum of the x y and z
        // radii, creating a sphere that is large enough to contain the original 
        // squished sphere.
        transformedSphere.Radius = Math.Max(scale3.X, Math.Max(scale3.Y, scale3.Z));
        // transforming the center of the sphere is much easier. we can just use 
        // Vector3.Transform to transform the center vector. notice that we're using
        // Transform instead of TransformNormal because in this case we DO want to 
        // take translation into account.
        transformedSphere.Center = Vector3.Transform(sphere.Center, transform);
        return transformedSphere;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...