コード例 #1
0
        protected override void calculateSampling(VolumeBrick brick)
        {
            Matrix modelview        = DrawArgs.Instance.WorldCamera.AbsoluteViewMatrix;
            Matrix modelviewInverse = Matrix.Invert(modelview);

            GMBoundingBox volumeBox = brick.VolumeBox.Clone() as GMBoundingBox;

            volumeBox.Transformation(modelview);

            /*
             * int minIndex;
             * int maxIndex;
             * minIndex = 0;
             * maxIndex = 7;
             * for (int i = 0; i < 8; i++)
             * {
             *  if (volumeBox.Corners[minIndex].Z > volumeBox.Corners[i].Z) minIndex = i;
             *  if (volumeBox.Corners[maxIndex].Z < volumeBox.Corners[i].Z) maxIndex = i;
             * }
             *
             * Vector3 maxv = new Vector3(modelviewInverse.M31 * volumeBox.Corners[maxIndex].Z,
             *                         modelviewInverse.M32 * volumeBox.Corners[maxIndex].Z,
             *                         modelviewInverse.M33 * volumeBox.Corners[maxIndex].Z);
             * Vector3 minv = new Vector3(modelviewInverse.M31 * volumeBox.Corners[minIndex].Z,
             *                         modelviewInverse.M32 * volumeBox.Corners[minIndex].Z,
             *                         modelviewInverse.M33 * volumeBox.Corners[minIndex].Z);
             */

            //_samples = 3000;
            _delta = (float)((DrawArgs.Camera.WorldRadius + 480000) / (double)_samples);
        }
コード例 #2
0
        public VolumeBrick(DVRBase dvr, float minX, float minY, float minZ, float sepDisX, float sepDisY, float sepDisZ, int ix, int iy, int nx, int ny, int nz)
        {
            _dvr     = dvr;
            _minX    = minX;
            _minY    = minY;
            _minZ    = minZ;
            _sepDisX = sepDisX;
            _sepDisY = sepDisY;
            _sepDisZ = sepDisZ;
            _ix      = ix;
            _iy      = iy;
            _nx      = nx;
            _ny      = ny;

            VolumeTexture textTure1 = null;
            VolumeTexture textTure2 = null;

            textTure1 = new VolumeTexture(DrawArgs.Device, nx, ny, nz, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
            textTure2 = new VolumeTexture(DrawArgs.Device, nx, ny, nz, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
            _texture.Add(textTure1);
            _texture.Add(textTure2);

            #region create texture box
            _textureBox = new GMBoundingBox(new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 0), new Vector3(0, 1, 0),
                                            new Vector3(0, 0, 1), new Vector3(1, 0, 1), new Vector3(1, 1, 1), new Vector3(0, 1, 1));

            minX += sepDisX * ix;
            minY += sepDisY * iy;

            //create volume box
            float vbXWidth = 0f;
            float vbYWidth = 0f;
            float vbZWidth = 0f;
            vbXWidth = sepDisX * nx;
            vbYWidth = sepDisY * ny;
            vbZWidth = sepDisZ * nz;
            Vector3 vb0 = GMMaths.SphericalToCartesian(minY, minX, DrawArgs.World.EquatorialRadius + (double)minZ);
            Vector3 vb1 = GMMaths.SphericalToCartesian(minY, minX + vbXWidth, DrawArgs.World.EquatorialRadius + (double)minZ);
            Vector3 vb2 = GMMaths.SphericalToCartesian(minY + vbYWidth, minX + vbXWidth, DrawArgs.World.EquatorialRadius + (double)minZ);
            Vector3 vb3 = GMMaths.SphericalToCartesian(minY + vbYWidth, minX, DrawArgs.World.EquatorialRadius + (double)minZ);
            Vector3 vb4 = GMMaths.SphericalToCartesian(minY, minX, DrawArgs.World.EquatorialRadius + (double)minZ + (double)vbZWidth);
            Vector3 vb5 = GMMaths.SphericalToCartesian(minY, minX + vbXWidth, DrawArgs.World.EquatorialRadius + (double)minZ + (double)vbZWidth);
            Vector3 vb6 = GMMaths.SphericalToCartesian(minY + vbYWidth, minX + vbXWidth, DrawArgs.World.EquatorialRadius + (double)minZ + (double)vbZWidth);
            Vector3 vb7 = GMMaths.SphericalToCartesian(minY + vbYWidth, minX, DrawArgs.World.EquatorialRadius + (double)minZ + (double)vbZWidth);
            //       7*--------*6
            //       /|       /|
            //      / |      / |
            //     /  |     /  |
            //    /  3*----/---*2
            //  4*--------*5  /
            //   |  /     |  /
            //   | /      | /
            //   |/       |/
            //  0*--------*1
            _volumeBox = new GMBoundingBox(vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7);
            _center    = _volumeBox.CalculateCenter();

            #endregion
        }
コード例 #3
0
        /// <summary>
        /// 计算slice面与box的相交结果
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="spn"></param>
        /// <param name="volumeBox"></param>
        /// <param name="verts"></param>
        /// <param name="textureBox"></param>
        /// <param name="tverts"></param>
        /// <param name="rotatedBox"></param>
        /// <param name="rverts"></param>
        /// <returns></returns>
        public int intersect(Vector3 sp, Vector3 spn, GMBoundingBox volumeBox, Vector3[] verts, GMBoundingBox textureBox,
                             Vector3[] tverts, GMBoundingBox rotatedBox, Vector3[] rverts, int minIndex, int maxIndex)
        {
            int intersections = 0;

            for (int i = 0; i < 12; i++)
            {
                Vector3 p0 = volumeBox.Corners[edges[i, 0]];
                Vector3 p1 = volumeBox.Corners[edges[i, 1]];
                float   t  = Vector3.Dot(spn, (sp - p0)) / Vector3.Dot(spn, (p1 - p0));

                if ((t >= 0) && (t <= 1))
                {
                    Vector3 t0 = textureBox.Corners[edges[i, 0]];
                    Vector3 t1 = textureBox.Corners[edges[i, 1]];

                    Vector3 r0 = rotatedBox.Corners[edges[i, 0]];
                    Vector3 r1 = rotatedBox.Corners[edges[i, 1]];

                    // Compute the line intersection
                    verts[intersections].X = (p0.X + t * (p1.X - p0.X));
                    verts[intersections].Y = (p0.Y + t * (p1.Y - p0.Y));
                    verts[intersections].Z = (p0.Z + t * (p1.Z - p0.Z));

                    // Compute the texture interseciton
                    tverts[intersections].X = (clamp(t0.X + t * (t1.X - t0.X), 0f, 1f));
                    tverts[intersections].Y = (clamp(t0.Y + t * (t1.Y - t0.Y), 0f, 1f));
                    tverts[intersections].Z = (clamp(t0.Z + t * (t1.Z - t0.Z), 0f, 1f));

                    // Compute view coordinate intersection
                    rverts[intersections].X = (r0.X + t * (r1.X - r0.X));
                    rverts[intersections].Y = (r0.Y + t * (r1.Y - r0.Y));
                    rverts[intersections].Z = (r0.Z + t * (r1.Z - r0.Z));

                    intersections++;
                }
            }

            return(intersections);
        }
コード例 #4
0
        /// <summary>
        /// Calculate the sampling distance
        /// </summary>
        protected virtual void calculateSampling(VolumeBrick brick)
        {
            Matrix modelview        = DrawArgs.Instance.WorldCamera.AbsoluteViewMatrix;
            Matrix modelviewInverse = Matrix.Invert(modelview);

            GMBoundingBox volumeBox = brick.VolumeBox.Clone() as GMBoundingBox;

            volumeBox.Transformation(modelview);

            //计算在视觉矩阵下离视点最远与最近的角点
            int minIndex;
            int maxIndex;

            minIndex = 0;
            maxIndex = 7;
            for (int i = 0; i < 8; i++)
            {
                if (volumeBox.Corners[minIndex].Z > volumeBox.Corners[i].Z)
                {
                    minIndex = i;
                }
                if (volumeBox.Corners[maxIndex].Z < volumeBox.Corners[i].Z)
                {
                    maxIndex = i;
                }
            }

            Vector3 maxv = new Vector3(modelviewInverse.M31 * volumeBox.Corners[maxIndex].Z,
                                       modelviewInverse.M32 * volumeBox.Corners[maxIndex].Z,
                                       modelviewInverse.M33 * volumeBox.Corners[maxIndex].Z);
            Vector3 minv = new Vector3(modelviewInverse.M31 * volumeBox.Corners[minIndex].Z,
                                       modelviewInverse.M32 * volumeBox.Corners[minIndex].Z,
                                       modelviewInverse.M33 * volumeBox.Corners[minIndex].Z);

            float distance = (maxv - minv).Length();

            //_samples = 400;
            _delta = distance / _samples;
        }
コード例 #5
0
        protected override void DrawViewAlignedSlices(DrawArgs drawArgs, VolumeBrick brick, Matrix viewMatrix)
        {
            double outerplus = 480000, interplus = 100000;
            double r0 = drawArgs.WorldCamera.WorldRadius + interplus;
            double r1 = drawArgs.WorldCamera.WorldRadius + outerplus;
            //drawArgs.device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);

            GMBoundingBox textureBox = brick.TextureBox;
            GMBoundingBox volumeBox  = brick.VolumeBox;
            GMBoundingBox rotatedBox = volumeBox.Clone() as GMBoundingBox;

            rotatedBox.Transformation(viewMatrix);
            GMVector3D tempp = drawArgs.WorldCamera.ReferenceCenter;
            //Vector3 dir = drawArgs.WorldCamera.Position - new Vector3((float)tempp.X, (float)tempp.Y, (float)tempp.Z);
            Vector3 dir = new Vector3(drawArgs.WorldCamera.Position.x - (float)tempp.X, drawArgs.WorldCamera.Position.y - (float)tempp.Y,
                                      drawArgs.WorldCamera.Position.z - (float)tempp.Z);

            Vector3 slicePlaneNormal = new Vector3(-dir.X, -dir.Y, -dir.Z);

            slicePlaneNormal.Normalize();



            calculateSampling(brick);

            drawArgs.device.VertexFormat = PositionTextured3D.Format;
            _effect.Technique            = "Spherical";
            _effect.SetTexture("VolumeTex", brick.Texture(0));
            if (_frameNow != nTime - 1) //当frameTime
            {
                _effect.SetTexture("VolumeTex2", brick.Texture(1));
            }
            else
            {
                _effect.SetTexture("VolumeTex2", brick.Texture(0));
            }

            _effect.Begin(FX.None);
            _effect.BeginPass(0);

            if (true || calculatedSliceRay == Vector3.Zero || calculatedSliceRay != slicePlaneNormal)
            {
                calculatedSlices.Clear();


                //计算两个slice间距
                Vector3 sliceDelta = slicePlaneNormal * _delta;

                Vector3 center     = new Vector3(0, 0, 0);
                Vector3 slicePoint = center + ((float)r1 * slicePlaneNormal) - sliceDelta;

                Vector3 sliceOrtho;

                if (Vector3.Dot(slicePlaneNormal, new Vector3(1, 1, 0)) != 0.0)
                {
                    sliceOrtho = Vector3.Cross(slicePlaneNormal, new Vector3(1, 1, 0));
                }
                else
                {
                    sliceOrtho = Vector3.Cross(slicePlaneNormal, new Vector3(0, 1, 0));
                }
                sliceOrtho.Normalize();


                float left   = (brick.MinX + 180) / 360.0f;
                float buttom = (brick.MinY + 90) / 180.0f;
                float right  = (brick.MinX + 180 + brick._nx * brick.LonStep) / 360.0f;
                float upp    = (brick.MinY + 90 + brick._ny * brick.LatStep) / 180.0f;
                float lowest = brick.MinZ;

                for (int i = 0; i <= _samples; i++)
                {
                    float d = (center - slicePoint).Length();
                    if (r1 > d)
                    {
                        float rg0 = 0.0f;
                        float rg1 = (float)Math.Sqrt(r1 * r1 - d * d);
                        if (r0 > d)
                        {
                            rg0 = (float)Math.Sqrt(r0 * r0 - d * d);
                        }

                        int m = 0;
                        PositionTextured3D[] d3dVerts = new PositionTextured3D[90];
                        for (double theta = -Math.PI / 20.0; theta <= 2 * Math.PI; theta += Math.PI / 20.0)
                        {
                            Vector3 v = sliceOrtho * (float)Math.Cos(theta) + (float)Math.Sin(theta) * Vector3.Cross(slicePlaneNormal, sliceOrtho);
                            v.Normalize();

                            Vector3 v0 = slicePoint + v * rg0;
                            Vector3 v1 = slicePoint + v * rg1;

                            Vector3 LonLat0 = GMMaths.CartesianToSpherical2(v0.X, v0.Y, v0.Z);
                            Vector3 LonLat1 = GMMaths.CartesianToSpherical2(v1.X, v1.Y, v1.Z);

                            if (LonLat0.Z >= max)
                            {
                                max = LonLat0.Z;
                            }
                            if (LonLat1.Z >= max)
                            {
                                max = LonLat1.Z;
                            }
                            if (LonLat0.Z <= min)
                            {
                                min = LonLat0.Z;
                            }
                            if (LonLat1.Z <= min)
                            {
                                min = LonLat1.Z;
                            }

                            Vector3 t0 = new Vector3(0, 0, 0);
                            Vector3 t1 = new Vector3(0, 0, 0);

                            t0.X = (LonLat0.Z + 180) / 360.0f;
                            t0.Y = (LonLat0.Y + 90.0f) / 180.0f;
                            t0.Z = 1.0f - (v0.Length() - (float)r0) / (float)(outerplus - interplus);
                            t1.X = (LonLat1.Z + 180) / 360.0f;
                            t1.Y = (LonLat1.Y + 90.0f) / 180.0f;
                            t1.Z = 1.0f - (v1.Length() - (float)r0) / (float)(outerplus - interplus);

                            t0.X = (t0.X - left) / (right - left);
                            t0.Y = (t0.Y - buttom) / (upp - buttom);
                            t1.X = (t1.X - left) / (right - left);
                            t1.Y = (t1.Y - buttom) / (upp - buttom);

                            d3dVerts[m].X  = v0.X;
                            d3dVerts[m].Y  = v0.Y;
                            d3dVerts[m].Z  = v0.Z;
                            d3dVerts[m].Tu = t0.X;
                            d3dVerts[m].Tv = t0.Y;
                            d3dVerts[m].Tw = t0.Z;
                            m++;
                            d3dVerts[m].X  = v1.X;
                            d3dVerts[m].Y  = v1.Y;
                            d3dVerts[m].Z  = v1.Z;
                            d3dVerts[m].Tu = t1.X;
                            d3dVerts[m].Tv = t1.Y;
                            d3dVerts[m].Tw = t1.Z;
                            m++;
                        }
                        drawArgs.device.DrawUserPrimitives(PrimitiveType.TriangleStrip, m - 4, d3dVerts);

                        calculatedSlices.Add(d3dVerts);
                    }
                    slicePoint -= sliceDelta;
                }
            }
            else
            {
                for (int i = 0; i < calculatedSlices.Count; i++)
                {
                    drawArgs.device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 80, calculatedSlices[i]);
                }
            }


            _effect.EndPass();
            _effect.End();

            calculatedSliceRay = slicePlaneNormal;
        }
コード例 #6
0
        protected virtual void DrawViewAlignedSlices(DrawArgs drawArgs, VolumeBrick brick, Matrix viewMatrix)
        {
            try
            {
                GMBoundingBox textureBox = brick.TextureBox;
                GMBoundingBox volumeBox  = brick.VolumeBox;
                GMBoundingBox rotatedBox = volumeBox.Clone() as GMBoundingBox;
                rotatedBox.Transformation(viewMatrix);

                //计算在视觉矩阵下离视点最远与最近的角点
                int minIndex;
                int maxIndex;
                minIndex = 0;
                maxIndex = 7;
                for (int i = 0; i < 8; i++)
                {
                    // z
                    if (rotatedBox.Corners[minIndex].Z > rotatedBox.Corners[i].Z)
                    {
                        minIndex = i;
                    }
                    if (rotatedBox.Corners[maxIndex].Z < rotatedBox.Corners[i].Z)
                    {
                        maxIndex = i;
                    }
                }

                //计算切割起算点
                Vector3 slicePoint = volumeBox.Corners[minIndex];

                //计算slicePlaneNormal = Vector(0,1,0)  * InvertedViewMatrix;
                Matrix  invertedViewMatrix = Matrix.Invert(viewMatrix);
                Vector3 slicePlaneNormal   = new Vector3(invertedViewMatrix.M31, invertedViewMatrix.M32, invertedViewMatrix.M33);
                slicePlaneNormal.Normalize();

                calculateSampling(brick);
                //计算两个slice间距
                Vector3 sliceDelta = slicePlaneNormal * _delta;

                //
                // Calculate edge intersections between the plane and the boxes
                //
                Vector3[] verts  = new Vector3[6];  // for edge intersections
                Vector3[] tverts = new Vector3[6];  // for texture intersections
                Vector3[] rverts = new Vector3[6];  // for transformed edge intersections

                drawArgs.device.VertexFormat = PositionTextured3D.Format;

                if (isUsingLight)
                {
                    _effect.Technique = "TextureTD_Lighting";
                }
                else
                {
                    _effect.Technique = "TextureTD";
                }

                _effect.SetValue("worldMatrix", drawArgs.device.GetTransform(TransformState.World));
                _effect.SetValue("viewMatrix", drawArgs.device.GetTransform(TransformState.View));
                _effect.SetValue("WorldViewProj", drawArgs.device.GetTransform(TransformState.World) * drawArgs.device.GetTransform(TransformState.View) * drawArgs.device.GetTransform(TransformState.Projection));

                Matrix mi = drawArgs.device.GetTransform(TransformState.World) * drawArgs.device.GetTransform(TransformState.View);
                mi.Invert();
                mi = Matrix.Transpose(mi);
                _effect.SetValue("normalMat", mi);

                _effect.SetTexture("VolumeTex", brick.Texture(0));
                if (_frameNow != nTime - 1) //当frameTime
                {
                    _effect.SetTexture("VolumeTex2", brick.Texture(1));
                }
                else
                {
                    _effect.SetTexture("VolumeTex2", brick.Texture(0));
                }
                //zxq 修改库后变化
                int oldAEnable     = drawArgs.device.GetRenderState(RenderState.AlphaBlendEnable);
                int oldSourceBlend = drawArgs.device.GetRenderState(RenderState.SourceBlend);
                int oldDesBlend    = drawArgs.device.GetRenderState(RenderState.DestinationBlend);
                drawArgs.device.SetRenderState(RenderState.AlphaBlendEnable, true);
                drawArgs.device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
                drawArgs.device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);

                _effect.Begin(FX.None);
                _effect.BeginPass(0);

                for (int i = 0; i <= _samples; i++)
                {
                    int[] order = new int[6] {
                        0, 1, 2, 3, 4, 5
                    };
                    int size = 0;
                    //if (i < 0 | i > 100) continue;
                    //
                    // 计算slice面片和box的交点
                    //
                    size = intersect(slicePoint, slicePlaneNormal, volumeBox, verts, textureBox, tverts, rotatedBox, rverts, minIndex, maxIndex);
                    //
                    // 计算交点的凸壳
                    //
                    findVertexOrder(rverts, order, size);

                    //至少有三个点,绘制面
                    if (size >= 3)
                    {
                        PositionTextured3D[] d3dVerts = new PositionTextured3D[size];
                        for (int fori = 0; fori < size; fori++)
                        {
                            d3dVerts[fori].X  = verts[order[fori]].X;
                            d3dVerts[fori].Y  = verts[order[fori]].Y;
                            d3dVerts[fori].Z  = verts[order[fori]].Z;
                            d3dVerts[fori].Tu = tverts[order[fori]].X;
                            d3dVerts[fori].Tv = tverts[order[fori]].Y;
                            d3dVerts[fori].Tw = tverts[order[fori]].Z;
                        }

                        drawArgs.device.DrawUserPrimitives(PrimitiveType.TriangleFan, size - 2, d3dVerts);
                    }

                    //下一slice平面
                    slicePoint += sliceDelta;
                }
                _effect.EndPass();
                _effect.End();
                //zxq 修改库后变化
                drawArgs.device.SetRenderState(RenderState.AlphaBlendEnable, oldAEnable);
                drawArgs.device.SetRenderState(RenderState.SourceBlend, oldSourceBlend);
                drawArgs.device.SetRenderState(RenderState.DestinationBlend, oldDesBlend);
            }
            catch (Exception ex)
            { }
        }