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; }
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) { } }