/// <summary> /// Random direction around the [0,0,1] vector. /// Normal distribution is used, using required variance. /// </summary> /// <param name="rnd">Random generator to be used.</param> /// <param name="variance">Variance of the deviation angle in radians.</param> /// <returns></returns> public static Vector3d RandomDirectionNormal(RandomJames rnd, double variance) { // result: [0,0,1] * rotX(deviation) * rotZ(orientation) double deviation = rnd.Normal(0.0, variance); double orientation = rnd.RandomDouble(0.0, Math.PI); Matrix4d mat = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation); return(new Vector3d(mat.Row2)); // [0,0,1] * mat }
/// <summary> From current lookat, calculate eyeposition, given a camera angle and a distance</summary> public static Vector3d CalculateEyePositionFromLookat(this Vector3d lookat, Vector2d cameradirdegreesp, double distance) { Matrix4d transform = Matrix4d.Identity; // identity nominal matrix, dir is in degrees transform *= Matrix4d.CreateRotationX((cameradirdegreesp.X * Math.PI / 180.0f)); // we rotate the camera vector around X and Y to get a vector which points from eyepos to lookat pos transform *= Matrix4d.CreateRotationY((cameradirdegreesp.Y * Math.PI / 180.0f)); Vector3d eyerel = Vector3d.Transform(new Vector3d(0, 1, 0), transform); // the 0,1,0 sets the axis of the camera dir return(lookat - eyerel * distance); }
/// <summary>Calculate the Projection matrix - projects the 3d model space to the 2D screen</summary> public void CalculateModelMatrix(Vector3d lookatd, Vector3d eyepositiond, double camerarotation) { LookAt = new Vector3((float)lookatd.X, (float)lookatd.Y, (float)lookatd.Z); // record for shader use EyePosition = new Vector3((float)eyepositiond.X, (float)eyepositiond.Y, (float)eyepositiond.Z); EyeDistance = (float)((lookatd - eyepositiond).Length); // System.Diagnostics.Debug.WriteLine($"CMM {lookat} {eyeposition} dist {EyeDistance} {cameradirection} {camerarotation}"); Matrix4d mat; if (InPerspectiveMode) { Vector3d camnormal = new Vector3d(0, ModelAxisPositiveZAwayFromViewer ? -1 : 1, 0); if (camerarotation != 0) // if we have camera rotation, then rotate the up vector { Matrix4d rot = Matrix4d.CreateRotationZ((float)camerarotation.Radians()); camnormal = Vector3d.Transform(camnormal, rot); } mat = Matrix4d.LookAt(eyepositiond, lookatd, camnormal); // from eye, look at target, with normal giving the rotation of the look } else { Size scr = ViewPort.Size; double orthoheight = (OrthographicDistance / 5.0f) * scr.Height / scr.Width; // this comes from the projection calculation, and allows us to work out the scale factor the eye vs lookat has double scaler = orthoheight / EyeDistance; // no create scale, do it manually. Matrix4d scale = new Matrix4d(new Vector4d(scaler, 0, 0, 0), new Vector4d(0, scaler, 0, 0), new Vector4d(0, 0, scaler, 0), new Vector4d(0, 0, 0, 1)); mat = Matrix4d.CreateTranslation(-lookatd.X, 0, -lookatd.Z); // we offset by the negative of the position to give the central look mat = Matrix4d.Mult(mat, scale); // translation world->View = scale + offset Matrix4d rotcam = Matrix4d.CreateRotationX(90.0 * Math.PI / 180.0f); // flip 90 along the x axis to give the top down view mat = Matrix4d.Mult(mat, rotcam); } // and turn it to float model matrix ModelMatrix = new Matrix4((float)mat.M11, (float)mat.M12, (float)mat.M13, (float)mat.M14, (float)mat.M21, (float)mat.M22, (float)mat.M23, (float)mat.M24, (float)mat.M31, (float)mat.M32, (float)mat.M33, (float)mat.M34, (float)mat.M41, (float)mat.M42, (float)mat.M43, (float)mat.M44); //System.Diagnostics.Debug.WriteLine("MM\r\n{0}", ModelMatrix); ProjectionModelMatrix = Matrix4.Mult(ModelMatrix, ProjectionMatrix); // order order order ! so important. CountMatrixCalcs++; }
/// <summary> /// Random direction around the givent center vector. /// Normal distribution is used, using required variance. /// </summary> /// <param name="rnd">Random generator to be used.</param> /// <param name="dir">Central direction.</param> /// <param name="variance">Variance of the deviation angle in radians.</param> /// <returns></returns> public static Vector3d RandomDirectionNormal(RandomJames rnd, Vector3d dir, double variance) { // Matrix3d fromz: [0,0,1] -> dir // Vector4d delta: [0,0,1] * rotX(deviation) * rotZ(orientation) // result: delta * fromz dir.Normalize(); Vector3d axis1, axis2; GetAxes(ref dir, out axis1, out axis2); Matrix4d fromz = new Matrix4d(new Vector4d(axis1), new Vector4d(axis2), new Vector4d(dir), Vector4d.UnitW); //fromz.Transpose(); double deviation = rnd.Normal(0.0, variance); double orientation = rnd.RandomDouble(0.0, Math.PI); Matrix4d mat = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation) * fromz; return(new Vector3d(mat.Row2)); // [0,0,1] * mat }
private void WriteNextMtx(int hnumber, sbyte bnumber, sbyte pnumber, Matrix4d testmtx, ref int ofs) { sbyte child = Hierarchies[hnumber][bnumber].Child; sbyte sibling = Hierarchies[hnumber][bnumber].Sibling; Matrix4d localmtx = testmtx; localmtx = Matrix4d.Mult(Matrix4d.CreateTranslation(Hierarchies[hnumber][bnumber].Translation), testmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationZ(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Z / 182.0444444f)), localmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationY(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Y / 182.0444444f)), localmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationX(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.X / 182.0444444f)), localmtx); if (Hierarchies[hnumber][bnumber].DisplayList != 0) { WriteMtxData(localmtx.M11, hnumber, ref ofs); WriteMtxData(localmtx.M12, hnumber, ref ofs); WriteMtxData(localmtx.M13, hnumber, ref ofs); WriteMtxData(localmtx.M14, hnumber, ref ofs); WriteMtxData(localmtx.M21, hnumber, ref ofs); WriteMtxData(localmtx.M22, hnumber, ref ofs); WriteMtxData(localmtx.M23, hnumber, ref ofs); WriteMtxData(localmtx.M24, hnumber, ref ofs); WriteMtxData(localmtx.M31, hnumber, ref ofs); WriteMtxData(localmtx.M32, hnumber, ref ofs); WriteMtxData(localmtx.M33, hnumber, ref ofs); WriteMtxData(localmtx.M34, hnumber, ref ofs); WriteMtxData(localmtx.M41, hnumber, ref ofs); WriteMtxData(localmtx.M42, hnumber, ref ofs); WriteMtxData(localmtx.M43, hnumber, ref ofs); WriteMtxData(localmtx.M44, hnumber, ref ofs); ofs += 0x20; } if (child > -1 && child != bnumber) { WriteNextMtx(hnumber, child, bnumber, localmtx, ref ofs); } if (sibling > -1 && sibling != bnumber) { WriteNextMtx(hnumber, sibling, pnumber, testmtx, ref ofs); } }
public override Entity Create(Region tregion, byte[] data) { DataStream ds = new DataStream(data); DataReader dr = new DataReader(ds); GenericCharacterEntity ent = new GenericCharacterEntity(tregion); ent.SetPosition(Location.FromDoubleBytes(dr.ReadBytes(24), 0)); ent.SetOrientation(new BEPUutilities.Quaternion(dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat())); ent.SetMass(dr.ReadFloat()); ent.CBAirForce = dr.ReadFloat(); ent.CBAirSpeed = dr.ReadFloat(); ent.CBCrouchSpeed = dr.ReadFloat(); ent.CBDownStepHeight = dr.ReadFloat(); ent.CBGlueForce = dr.ReadFloat(); ent.CBHHeight = dr.ReadFloat(); ent.CBJumpSpeed = dr.ReadFloat(); ent.CBMargin = dr.ReadFloat(); ent.CBMaxSupportSlope = dr.ReadFloat(); ent.CBMaxTractionSlope = dr.ReadFloat(); ent.CBProneSpeed = dr.ReadFloat(); ent.CBRadius = dr.ReadFloat(); ent.CBSlideForce = dr.ReadFloat(); ent.CBSlideJumpSpeed = dr.ReadFloat(); ent.CBSlideSpeed = dr.ReadFloat(); ent.CBStandSpeed = dr.ReadFloat(); ent.CBStepHeight = dr.ReadFloat(); ent.CBTractionForce = dr.ReadFloat(); ent.PreRot *= Matrix4d.CreateRotationX(dr.ReadFloat() * Utilities.PI180); ent.PreRot *= Matrix4d.CreateRotationY(dr.ReadFloat() * Utilities.PI180); ent.PreRot *= Matrix4d.CreateRotationZ(dr.ReadFloat() * Utilities.PI180); ent.mod_scale = dr.ReadFloat(); ent.PreRot = Matrix4d.Scale(ent.mod_scale) * ent.PreRot; ent.color = System.Drawing.Color.FromArgb(dr.ReadInt()); byte dtx = dr.ReadByte(); ent.Visible = (dtx & 1) == 1; ent.ShouldShine = (dtx & 32) == 32; int solidity = (dtx & (2 | 4 | 8 | 16)); if (solidity == 2) { ent.CGroup = CollisionUtil.Solid; } else if (solidity == 4) { ent.CGroup = CollisionUtil.NonSolid; } else if (solidity == (2 | 4)) { ent.CGroup = CollisionUtil.Item; } else if (solidity == 8) { ent.CGroup = CollisionUtil.Player; } else if (solidity == (2 | 8)) { ent.CGroup = CollisionUtil.Water; } else if (solidity == (2 | 4 | 8)) { ent.CGroup = CollisionUtil.WorldSolid; } else if (solidity == 16) { ent.CGroup = CollisionUtil.Character; } ent.model = tregion.TheClient.Models.GetModel(tregion.TheClient.Network.Strings.StringForIndex(dr.ReadInt())); dr.Close(); return(ent); }
/// <summary> /// 起動時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormRotationMatrix_Load(object sender, EventArgs e) { #region glControlの追加 (デザイナが壊れるため) // // glControlReciProObjects // this.glControlReciProObjects = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 248), Margin = new Padding(0), Name = "glControlReciProObjects", NodeCoefficient = 1, ProjWidth = 1D, Size = new Size(130, 130), }; this.glControlReciProObjects.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); // // glControlReciProAxes // this.glControlReciProAxes = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 114), Margin = new Padding(0), Name = "glControlReciProAxes", NodeCoefficient = 1, ProjWidth = 2.8D, Size = new Size(130, 130), }; glControlReciProAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlReciProGonio // this.glControlReciProGonio = new GLControlAlpha { AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(5, 114), Margin = new Padding(0), Name = "glControlReciProGonio", ProjWidth = 5D, Size = new Size(264, 264), }; glControlReciProGonio.WorldMatrixChanged += new EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); // // glControlExpObjects // this.glControlExpObjects = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 248), Margin = new Padding(0), Name = "glControlExpObjects", ProjWidth = 1D, Size = new Size(130, 130), }; this.glControlExpObjects.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlExpAxes // this.glControlExpAxes = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 114), Margin = new System.Windows.Forms.Padding(0), Name = "glControlExpAxes", ProjWidth = 2.8D, Size = new Size(130, 130), }; this.glControlExpAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlExpGonio // this.glControlExpGonio = new GLControlAlpha { AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(5, 114), Margin = new Padding(0), Name = "glControlExpGonio", ProjWidth = 5D, Size = new Size(264, 264), }; this.glControlExpGonio.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); groupBox2.Controls.Add(glControlExpObjects); groupBox2.Controls.Add(glControlExpAxes); groupBox2.Controls.Add(glControlExpGonio); groupBox1.Controls.Add(glControlReciProObjects); groupBox1.Controls.Add(glControlReciProAxes); groupBox1.Controls.Add(glControlReciProGonio); #endregion glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI); SetRotation(); numericBoxPhi.TextBoxBackColor = numericBoxExp1.TextBoxBackColor = Color.FromArgb(255, 180, 180, 0); numericBoxTheta.TextBoxBackColor = numericBoxExp2.TextBoxBackColor = Color.FromArgb(255, 0, 180, 180); numericBoxPsi.TextBoxBackColor = numericBoxExp3.TextBoxBackColor = Color.FromArgb(255, 180, 0, 180); numericBoxPhi.TextBoxForeColor = numericBoxExp1.TextBoxForeColor = numericBoxTheta.TextBoxForeColor = numericBoxExp2.TextBoxForeColor = numericBoxPsi.TextBoxForeColor = numericBoxExp3.TextBoxForeColor = Color.FromArgb(255, 255, 255, 255); }
private void ButtonViewIsometric_Click(object sender, EventArgs e) => glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI);
public void RotateX(double angle) { matrix = Matrix4d.CreateRotationX(angle) * matrix; inverse_matrix *= Matrix4d.CreateRotationX(-angle); }
/// <summary> /// This function opens a stream and reads the .obj file. /// !!So far It Assumes that the object described in the file /// is segmented into parts and that the file contains object part names i.e. vertex lists start with "o mesh_part_name" /// </summary> /// <param name="FileName"></param> public static List <Mesh3D> LoadOBJFile(string FilePath, bool X_Rotation, bool ignoreGroups, int filterIndex) { List <Mesh3D> results = new List <Mesh3D> (); int indexVertex = 0; int indexNormal = 0; int indexTexture = 0; int indexFacet = 0; int FacetCount = 0; List <string> GroupName = new List <string>(); string FileName = Path.GetFileName(FilePath.Replace((filterIndex == 1) ? ".obj" : ".smf", ".")); List <List <Vector3> > VertexList = new List <List <Vector3> >(); List <List <Vector3> > NormalList = new List <List <Vector3> >(); List <List <Vector3> > ColorList = new List <List <Vector3> >(); List <List <Vector2> > TextureList = new List <List <Vector2> >(); List <List <uint> > FacetList = new List <List <uint> >(); List <List <List <int> > > NeighborsVertices = new List <List <List <int> > >(); List <List <List <int> > > NeighborsFacets = new List <List <List <int> > >(); VertexList.Add(new List <Vector3>()); NormalList.Add(new List <Vector3>()); ColorList.Add(new List <Vector3>()); TextureList.Add(new List <Vector2>()); FacetList.Add(new List <uint>()); NeighborsVertices.Add(new List <List <int> >()); NeighborsFacets.Add(new List <List <int> >()); using (StreamReader sreader = new StreamReader(FilePath, Encoding.Default)) { try { //While we are not yet at the end of stream while (!sreader.EndOfStream) { string Line = sreader.ReadLine(); string[] currentLine = Line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (currentLine.Length == 0) { continue; } switch (currentLine[0]) { case "mtllib": { string mtlFile = Path.GetDirectoryName(FilePath) + '\\' + currentLine[1]; LoadMTLFile(mtlFile); break; } case "v": { try { Vector3d TransformedV; Vector3d nV = new Vector3d(Convert.ToDouble(currentLine[1]), Convert.ToDouble(currentLine[2]), Convert.ToDouble(currentLine[3])); Vector3d ColorV = new Vector3d(); if (currentLine.Length > 4) { ColorV = new Vector3d(Convert.ToDouble(currentLine[4]), Convert.ToDouble(currentLine[5]), Convert.ToDouble(currentLine[6])); } if (X_Rotation) { Matrix4d R = Matrix4d.CreateRotationX(-Math.PI / 2.0); Vector3d.Transform(ref nV, ref R, out TransformedV); } else { TransformedV = nV; } VertexList[indexVertex].Add(new Vector3((float)TransformedV.X, (float)TransformedV.Y, (float)TransformedV.Z)); //X,Y,Z ColorList[indexVertex].Add(new Vector3((float)ColorV.X, (float)ColorV.Y, (float)ColorV.Z)); //X,Y,Z NeighborsVertices[indexVertex].Add(new List <int>()); NeighborsFacets[indexVertex].Add(new List <int>()); } catch (Exception ex) { throw new Exception("Vertex Storing:" + ex.Message); } break; } case "vt": { TextureList[indexTexture].Add(new Vector2(Convert.ToSingle(currentLine[1]), Convert.ToSingle(currentLine[2]))); break; } case "vn": { NormalList[indexNormal].Add(new Vector3((float)Convert.ToDouble(currentLine[1]), (float)Convert.ToDouble(currentLine[2]), (float)Convert.ToDouble(currentLine[3]))); break; } case "vp": { break; } case "f": { uint VertexCount = 0; if (!ignoreGroups) { for (int i = 0; i < indexFacet; ++i) { VertexCount += (uint)VertexList[i].Count; } } uint[] vertices = new uint[3]; for (int i = 1; i < currentLine.Length; ++i) { string[] vData = currentLine[i].Split('/'); //In obj files vertex numbering in a facet declaration statement is 1-based. //So we subtruct 1 from each reference because we want 0-based vertices[i - 1] = Convert.ToUInt32(vData[0]) - 1 - VertexCount; FacetList[indexFacet].Add(vertices[i - 1]); } // Neighborhood... for (int i = 0; i < 3; ++i) { NeighborsFacets[indexFacet][(int)vertices[i]].Add(FacetCount); if (!NeighborsVertices[indexFacet][(int)vertices[i]].Contains((int)vertices[(i + 1) % 3])) { NeighborsVertices[indexFacet][(int)vertices[i]].Add((int)vertices[(i + 1) % 3]); } if (!NeighborsVertices[indexFacet][(int)vertices[i]].Contains((int)vertices[(i + 2) % 3])) { NeighborsVertices[indexFacet][(int)vertices[i]].Add((int)vertices[(i + 2) % 3]); } } FacetCount++; break; } case "g": { if (ignoreGroups || currentLine.Length == 1) { break; } if (ColorList[indexVertex].Count > 0) { ColorList.Add(new List <Vector3>()); } if (VertexList[indexVertex].Count > 0) { indexVertex++; VertexList.Add(new List <Vector3>()); NeighborsVertices.Add(new List <List <int> >()); NeighborsFacets.Add(new List <List <int> >()); } if (NormalList[indexNormal].Count > 0) { indexNormal++; NormalList.Add(new List <Vector3>()); } if (TextureList[indexTexture].Count > 0) { indexTexture++; TextureList.Add(new List <Vector2>()); } if (FacetList[indexFacet].Count > 0) { indexFacet++; FacetList.Add(new List <uint>()); FacetCount = 0; } GroupName.Add(FileName + currentLine[1].ToString()); break; } case "o": break; case "#": break; }//switch } } catch (Exception ex) { results = null; MessageBox.Show(ex.ToString()); } } results = new List <Mesh3D>(); if (GroupName.Count == 0) { GroupName.Add(FileName.Substring(0, FileName.Length - 1)); } for (int i = 0; i < GroupName.Count; i++) { Vector3[] normals = (i < NormalList.Count) ? NormalList[i].ToArray() : null; Vector3[] colors = (i < ColorList.Count) ? ColorList[i].ToArray() : null; Vector2[] tex_indices = (i < TextureList.Count) ? TextureList[i].ToArray() : null; uint[] indices = FacetList[i].ToArray(); Mesh3D mesh = new Mesh3D( i, GroupName[i], VertexList[i].ToArray(), normals, colors, tex_indices, indices, NeighborsVertices[i].ToArray(), NeighborsFacets[i].ToArray() ); results.Add(mesh); } return(results); }
private void Form1_Load(object sender, EventArgs e) { try { // 加载ArcGIS地图 string fileName = ConfigurationManager.AppSettings["3DDFile"]; this.globe3DControl1.Load3DDFile(fileName); string contentRoot = ConfigurationManager.AppSettings["ContentRoot"]; // 初始化三维渲染 this.globe3DControl1.Initialize3D(0.001, 2.5, true, true, contentRoot); this.globe3DControl1.ShowSun = false; this.globe3DControl1.ShowMoon = false; // Fix me: 这里需要手动初始化一下DetectRange的硬件资源 // 能否放在一个统一的扩展初始化函数中? DetectRange.InitGeometries(globe3DControl1.World.World.ContentManager); // 制作雷达范围的测试数据 // 360个方向,5个高度层? // TODO: 先通过完整的圆球来测试,然后再测试有随机遮蔽的情况 #region P-雷达范围 // 改为通过添加实体的方式来测试? m_RadarLayer = globe3DControl1.World.AddLayer("radarLayer"); Entity3D radarEntity = m_RadarLayer.AddEntity("radar01"); // radarEntity.Visible = false; radarEntity.Color = Vector4.One; GeographicCoordinateTransform transformCmp = new GeographicCoordinateTransform(); transformCmp.AlwaysFaceGeoCenter = true; transformCmp.LocalPose.Scale = new Vector3d(100, 100, 100); transformCmp.Longitude = 120; transformCmp.Latitude = 30; transformCmp.Height = 0; radarEntity.AddComponent(transformCmp); DetectRangeComponent detectRange = new DetectRangeComponent(); // DetectRange detectRange = new DetectRange(); // 创建一个变换矩阵 // 缩小后放在北极? Matrix4d matScale = Matrix4d.Scale(0.0001); Matrix4d matTran = Matrix4d.CreateTranslation(0, 1, 0); detectRange.UseSimpleNormal = true; // detectRange.Transform = matScale * matTran; detectRange.Color = new Vector4(0.8f, 1, 0.8f, 0.9f); detectRange.ScanColor = new Vector4(1.0f, 0.6f, 0.2f, 0.5f); // TODO: 创建随机的360度的范围的遮蔽数据 // 通过Perlin噪声来模拟 double[] occlusion = new double[360]; PerlinNoise noise = new PerlinNoise(99); for (int i = 0; i < 360; i++) { double val = (noise.Noise(2 * i / 180.0, 2 * i / 180.0, -0.5)) * 0.7 + (noise.Noise(4 * i / 180.0, 4 * i / 180.0, 0)) * 0.2 + (noise.Noise(8 * i / 180.0, 8 * i / 180.0, 0.5)) * 0.1; val = Math.Max(val * 3, 0); occlusion[i] = val * 6000 + 800; } detectRange.Ranges.Add(CreateHorizRange(300, 1000, occlusion)); detectRange.Ranges.Add(CreateHorizRange(600, 2500, occlusion)); detectRange.Ranges.Add(CreateHorizRange(800, 3500, occlusion)); detectRange.Ranges.Add(CreateHorizRange(1500, 4500, occlusion)); detectRange.Ranges.Add(CreateHorizRange(2000, 4400, occlusion)); detectRange.Ranges.Add(CreateHorizRange(2500, 4000, occlusion)); detectRange.Ranges.Add(CreateHorizRange(2300, 800, occlusion)); detectRange.RefreshGeometry(); radarEntity.AddComponent(detectRange); m_DetectRange = detectRange; #endregion // 创建雷达范围自定义图元 // 添加到场景中 // globe3DControl1.World.World.RenderScene.CustomRenderPrimitives.Add(detectRange); #region 扫描范围锥体 bool useSenceVolumePrim = false; if (useSenceVolumePrim) { // 直接用自定义图元测试 RectSenseVolume senceVolume = new RectSenseVolume(); senceVolume.Initialize(globe3DControl1.World.ContentManager); // 属性:变换矩阵 Matrix4d matRot = Matrix4d.CreateRotationX(Math.PI * 0.5); senceVolume.Transform = matRot * Matrix4d.CreateTranslation(0, -5.6, 0); senceVolume.HorizHalfAngle = 5.5; senceVolume.VertiHalfAngle = 10.5; senceVolume.Color = Vector4.One; globe3DControl1.World.World.RenderScene.CustomRenderPrimitives.Add(senceVolume); } else { // 用实体和组件测试 m_SatelliteLayer = globe3DControl1.World.AddLayer("satelliteLayer"); Entity3D satelliteEntity = m_SatelliteLayer.AddEntity("satellite01"); GeographicCoordinateTransform satTran = new GeographicCoordinateTransform(); satTran.AlwaysFaceGeoCenter = true; satTran.Longitude = 120; satTran.Latitude = 0; satTran.Height = 35800e3; satelliteEntity.AddComponent(satTran); Vector3d satellitePos = Globe3DCoordHelper.GraphicToCentric(satTran.Longitude, satTran.Latitude, satTran.Height); // 注意:卫星模型的视觉放大需要通过再加一个卫星模型子实体来实现,否则会影响传感器子实体 #region 大视场传感器 Entity3D sensorEntity = m_SatelliteLayer.AddEntity("sensor01"); sensorEntity.Parent = satelliteEntity; SRTTransformComponent sensorTran = new SRTTransformComponent(); // sensorTran.RotationX = 10; sensorEntity.AddComponent(sensorTran); CustomController.SensorAutoScanController sensorCtrl = new CustomController.SensorAutoScanController(); sensorEntity.AddComponent(sensorCtrl); RectSenseVolumeComponent sensorRange = new RectSenseVolumeComponent(globe3DControl1.World.ContentManager); sensorRange.HorizHalfAngle = 5.5; sensorRange.VertiHalfAngle = 10.5; sensorRange.Pickable = false; sensorRange.Color = new Vector4(1, 0.4f, 0, 0.2f);// Vector4.One; sensorRange.ScanPlanes.Add(new RectSenseVolume.ScanPlane() { CurrAngle = 0, Orientation = RectSenseVolume.ScanPlane.ScanOrientations.Vertical, Visible = true, Color = new Vector4(1, 0.2f, 0, 0.25f) }); //sensorRange.ScanPlanes.Add(new RectSenseVolume.ScanPlane() //{ // CurrAngle = 0, // Orientation = RectSenseVolume.ScanPlane.ScanOrientations.Horizontal, // Visible = true, // Color = new Vector4(0, 1, 0, 0.4f) //}); sensorRange.InvalidateScanPlanes(); sensorEntity.AddComponent(sensorRange); #endregion #region 小视场传感器 Entity3D smallSensorEntity = m_SatelliteLayer.AddEntity("sensor02"); smallSensorEntity.Parent = satelliteEntity; CustomController.SensorGridScanController sensorGridCtrl = new CustomController.SensorGridScanController(); sensorGridCtrl.MinHorizAngle = 2; sensorGridCtrl.MaxHorizAngle = 4; sensorGridCtrl.MinVertiAngle = 2; sensorGridCtrl.MaxVertiAngle = 4; sensorGridCtrl.NumHorizGrids = 2; sensorGridCtrl.NumVertiGrids = 2; sensorGridCtrl.MoveInterval = 0.75; sensorGridCtrl.StayInterval = 0.25; sensorGridCtrl.ScanSequence.Add(new System.Drawing.Point(0, 0)); sensorGridCtrl.ScanSequence.Add(new System.Drawing.Point(0, 1)); sensorGridCtrl.ScanSequence.Add(new System.Drawing.Point(1, 1)); sensorGridCtrl.ScanSequence.Add(new System.Drawing.Point(1, 0)); smallSensorEntity.AddComponent(sensorGridCtrl); SRTTransformComponent smallSensorTran = new SRTTransformComponent(); smallSensorEntity.AddComponent(smallSensorTran); RectSenseVolumeComponent smallSensorRange = new RectSenseVolumeComponent(globe3DControl1.World.ContentManager); smallSensorRange.HorizHalfAngle = 0.5; smallSensorRange.VertiHalfAngle = 0.5; smallSensorRange.Pickable = false; smallSensorRange.Color = new Vector4(0, 1, 0, 0.4f); smallSensorEntity.AddComponent(smallSensorRange); #endregion ////////////////////////////////////// uint precision = 30; double theta = 6.5; double range = 11; List <Vector3d> points = RadarIntersect((Vector3d)satellitePos, theta, range, precision); m_PackedMarkStyle = new PackedBillboardMaterialStyle(globe3DControl1.World.ContentManager); m_PackedMarkStyle.Texture = globe3DControl1.World.ContentManager.LoadTexture(@".\Resources\Textures\PackedIcons.png"); using (FileStream fs = new FileStream(@".\Resources\Textures\PackedIcons.xml", FileMode.Open, FileAccess.Read)) { XmlSerializer xs = new XmlSerializer(typeof(List <PackedImage>)); m_PackedMarkStyle.PackedImages = xs.Deserialize(fs) as List <PackedImage>; fs.Close(); // 如果加载失败怎么办 if (m_PackedMarkStyle.PackedImages == null) { throw new InvalidDataException("Failed loading packed image definition"); } } for (int i = 0; i < points.Count; i++) { Vector3d p = points[i]; Vector3d pos = Globe3DCoordHelper.CentricToGraphic(p.X, p.Y, p.Z); Entity3D markEntity = m_SatelliteLayer.AddEntity(i.ToString()); GeographicCoordinateTransform geoTf = new GeographicCoordinateTransform(); geoTf.Longitude = pos.X; geoTf.Latitude = pos.Y; geoTf.Height = pos.Z; markEntity.AddComponent(geoTf); BillboardComponent bgIcon = new BillboardComponent(); bgIcon.Pickable = true; bgIcon.Color = Vector4.One; bgIcon.Visible = true; bgIcon.Width = 20; bgIcon.Height = 20; // Fix me: 本billboard的偏移量在哪里进行比较好? bgIcon.Offset = new Vector2d(0, 0); bgIcon.MaterialStyle = m_PackedMarkStyle; // Fix me: 通过名称获得packed image index的操作在哪里进行比较好? bgIcon.PackID = m_PackedMarkStyle.GetPackIndexByName("bg.fw.png"); // 所有的组成部分使用统一的组ID bgIcon.GroupID = markEntity.ID; // 背景最先绘制 bgIcon.RenderOrder = 0; markEntity.AddComponent(bgIcon); } } #endregion // 摄像机操作 // 设置摄像机跟随预警机实体 globe3DControl1.CameraController.ObserveMode = Controls.GIS3D.Core.EntityComponent.Controller.GlobeCameraControllerComponent.CameraObserveMode.Free; // 修改摄像机的oriantationmode为surface globe3DControl1.CameraController.OrientationMode = GlobeCameraControllerComponent.CameraOrientationMode.NorthPole; globe3DControl1.CameraController.MinDistanceMeter = 200;// 30000; globe3DControl1.CameraController.CurViewDistance = 11400000; //this.globe3DControl1.World.GlobeCameraController.LowRange = 200000; this.globe3DControl1.World.GlobeCameraController.LowRange = 20000; this.globe3DControl1.World.GlobeCameraController.LowRangeLeanFactor = 0.2; //this.globe3DControl1.World.GlobeCameraController.LowRangeLeanFactor = 4; this.globe3DControl1.World.GlobeCameraController.AutoRotate = false; m_Simulator = new GlobeSimulator(); m_Simulator.Updated += new GlobeSimulator.UpdateEventHandler(m_Simulator_Updated); m_Simulator.StartSimulation(); m_SimTimer.Interval = 40; m_SimTimer.Tick += new EventHandler(m_SimTimer_Tick); m_SimTimer.Start(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); Debug.WriteLine(ex.ToString()); throw; } }