Esempio n. 1
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
        }
Esempio n. 2
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;
        }