Click here to Skip to main content
15,895,084 members
Articles / Desktop Programming / WPF

D3dScenePresenter - How to present and manipulate a 3D scene using MDX

Rate me:
Please Sign up or sign in to vote.
4.57/5 (14 votes)
15 Feb 2013CPOL14 min read 45.3K   1.6K   25  
This article shows how we can present a 3D scene and, perform common operations (zoom, rotate, move, zoom to specific region, adjust the camera to view the whole of the scene, and pick a 3D shape on a specific region on the rendered surface) on it, using Managed DirectX.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.DirectX;

namespace MdxScene
{
    // Define the BoundingBox as a struct, in order to use it on the stack (instead of the heap).
    public struct BoundingBox
    {
        public BoundingBox(Vector3 minimalValues, Vector3 maximalValues)
        {
            FrontTopLeftPosition = new Vector3(minimalValues.X, maximalValues.Y, maximalValues.Z);
            FrontTopRightPosition = new Vector3(maximalValues.X, maximalValues.Y, maximalValues.Z);
            FrontBottomLeftPosition = new Vector3(minimalValues.X, minimalValues.Y, maximalValues.Z);
            FrontBottomRightPosition = new Vector3(maximalValues.X, minimalValues.Y, maximalValues.Z);
            BackTopLeftPosition = new Vector3(minimalValues.X, maximalValues.Y, minimalValues.Z);
            BackTopRightPosition = new Vector3(maximalValues.X, maximalValues.Y, minimalValues.Z);
            BackBottomLeftPosition = new Vector3(minimalValues.X, minimalValues.Y, minimalValues.Z);
            BackBottomRightPosition = new Vector3(maximalValues.X, minimalValues.Y, minimalValues.Z);
        }

        // Hold the box's points' positions as different data-members (instead of an array),
        // for preventing using a memory allocation for the BoundingBox's operations.
        public Vector3 FrontTopLeftPosition;
        public Vector3 FrontTopRightPosition;
        public Vector3 FrontBottomLeftPosition;
        public Vector3 FrontBottomRightPosition;
        public Vector3 BackTopLeftPosition;
        public Vector3 BackTopRightPosition;
        public Vector3 BackBottomLeftPosition;
        public Vector3 BackBottomRightPosition;

        public void TransformCoordinates(Matrix transformationMatrix)
        {
            FrontTopLeftPosition.TransformCoordinate(transformationMatrix);
            FrontTopRightPosition.TransformCoordinate(transformationMatrix);
            FrontBottomLeftPosition.TransformCoordinate(transformationMatrix);
            FrontBottomRightPosition.TransformCoordinate(transformationMatrix);
            BackTopLeftPosition.TransformCoordinate(transformationMatrix);
            BackTopRightPosition.TransformCoordinate(transformationMatrix);
            BackBottomLeftPosition.TransformCoordinate(transformationMatrix);
            BackBottomRightPosition.TransformCoordinate(transformationMatrix);
        }

        public bool IsOutOfBoundingBox(Vector3 boxMinimalValues, Vector3 boxMaximalValues)
        {
            return IsOutOfBoundingBox(boxMinimalValues.X, boxMinimalValues.Y, boxMinimalValues.Z,
                                   boxMaximalValues.X, boxMaximalValues.Y, boxMaximalValues.Z);
        }

        public bool IsOutOfBoundingBox(float boxMinimalX, float boxMinimalY, float boxMinimalZ,
            float boxMaximalX, float boxMaximalY, float boxMaximalZ)
        {
            float thisMinimalX = GetMinimalX();
            float thisMinimalY = GetMinimalY();
            float thisMinimalZ = GetMinimalZ();
            float thisMaximalX = GetMaximalX();
            float thisMaximalY = GetMaximalY();
            float thisMaximalZ = GetMaximalZ();

            bool isOutOfXView = thisMinimalX > boxMaximalX || thisMaximalX < boxMinimalX;
            bool isOutOfYView = thisMinimalY > boxMaximalY || thisMaximalY < boxMinimalY;
            bool isOutOfZView = thisMinimalZ > boxMaximalZ || thisMaximalZ < boxMinimalZ;

            return isOutOfXView || isOutOfYView || isOutOfZView;
        }

        public float GetMinimalX()
        {
            return Min(FrontTopLeftPosition.X, FrontTopRightPosition.X, FrontBottomLeftPosition.X,
                       FrontBottomRightPosition.X, BackTopLeftPosition.X, BackTopRightPosition.X,
                       BackBottomLeftPosition.X, BackBottomRightPosition.X);
        }

        public float GetMinimalY()
        {
            return Min(FrontTopLeftPosition.Y, FrontTopRightPosition.Y, FrontBottomLeftPosition.Y,
                       FrontBottomRightPosition.Y, BackTopLeftPosition.Y, BackTopRightPosition.Y,
                       BackBottomLeftPosition.Y, BackBottomRightPosition.Y);
        }

        public float GetMinimalZ()
        {
            return Min(FrontTopLeftPosition.Z, FrontTopRightPosition.Z, FrontBottomLeftPosition.Z,
                       FrontBottomRightPosition.Z, BackTopLeftPosition.Z, BackTopRightPosition.Z,
                       BackBottomLeftPosition.Z, BackBottomRightPosition.Z);
        }

        public float GetMaximalX()
        {
            return Max(FrontTopLeftPosition.X, FrontTopRightPosition.X, FrontBottomLeftPosition.X,
                       FrontBottomRightPosition.X, BackTopLeftPosition.X, BackTopRightPosition.X,
                       BackBottomLeftPosition.X, BackBottomRightPosition.X);
        }

        public float GetMaximalY()
        {
            return Max(FrontTopLeftPosition.Y, FrontTopRightPosition.Y, FrontBottomLeftPosition.Y,
                       FrontBottomRightPosition.Y, BackTopLeftPosition.Y, BackTopRightPosition.Y,
                       BackBottomLeftPosition.Y, BackBottomRightPosition.Y);
        }

        public float GetMaximalZ()
        {
            return Max(FrontTopLeftPosition.Z, FrontTopRightPosition.Z, FrontBottomLeftPosition.Z,
                       FrontBottomRightPosition.Z, BackTopLeftPosition.Z, BackTopRightPosition.Z,
                       BackBottomLeftPosition.Z, BackBottomRightPosition.Z);
        }

        private float Min(float a, float b, float c, float d, float e, float f, float g, float h)
        {
            float minAB = a < b ? a : b;
            float minCD = c < d ? c : d;
            float minEF = e < f ? e : f;
            float minGH = g < h ? g : h;

            float minABCD = minAB < minCD ? minAB : minCD;
            float minEFGH = minEF < minGH ? minEF : minGH;

            return minABCD < minEFGH ? minABCD : minEFGH;

        }

        private float Max(float a, float b, float c, float d, float e, float f, float g, float h)
        {
            float maxAB = a > b ? a : b;
            float maxCD = c > d ? c : d;
            float maxEF = e > f ? e : f;
            float maxGH = g > h ? g : h;

            float maxABCD = maxAB > maxCD ? maxAB : maxCD;
            float maxEFGH = maxEF > maxGH ? maxEF : maxGH;

            return maxABCD > maxEFGH ? maxABCD : maxEFGH;
        }
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions