// Use this for initialization void Start () { if (IsGetFromDatabase) { LoadModelFromDataBase (); } else { // generate new mesh MyBlockMesher = new BlockMesher(); // MyBlockStructure = GetManager.GetDataManager ().GetBlockStructure(MyBlockStructureName); MyBlockStructure.Reset (); if (IsVaryScale) { float CurrentSize = MyBlockStructure.MyBlocks.Scale.x; float NewSize = CurrentSize * (Random.Range (MinimumVariation, MaximumVariation)); MyBlockStructure.MyBlocks.Scale += new Vector3 (NewSize, NewSize, NewSize); //MyBlockStructure.MyBlockTypes[0] = Random.Range(1,12); } //MyBlockStructure.UpdateBlockStructureWithType(); if (Type == 0) { MyBlockStructure.Sphere (Random.Range (1, 12), SphereSize); // 7 for cores MyBlockStructure.AddNoise (NoiseValue); } else { MyBlockStructure.MyBlocks.Size.y = 8; MyBlockStructure.Reset (); MyBlockStructure.Cylinder (2, SphereSize); } MyMesh = new MyMesh (); MyBlockMesher.UpdateMeshesOnThread (MyMesh, MyBlockStructure.MyBlocks); } }
private void StartMeshSimplification() { Mesh meshToSimplify = meshInput.sharedMesh; meshInput.transform.gameObject.SetActive(false); // // Change data structure and normalize // //Mesh -> MyMesh MyMesh myMeshToSimplify = new MyMesh(meshToSimplify); //From local to global space myMeshToSimplify.vertices = myMeshToSimplify.vertices.Select(x => meshInput.transform.TransformPoint(x.ToVector3()).ToMyVector3()).ToList(); //Normalize to 0-1 //this.normalizer = new Normalizer3(myMeshToSimplify.vertices); //We only need to normalize the vertices //myMeshToSimplify.vertices = normalizer.Normalize(myMeshToSimplify.vertices); HalfEdgeData3 myMeshToSimplify_HalfEdge = new HalfEdgeData3(myMeshToSimplify, HalfEdgeData3.ConnectOppositeEdges.Fast); //Start VisualizeMergeEdgesQEM visualizeThisAlgorithm = GetComponent <VisualizeMergeEdgesQEM>(); visualizeThisAlgorithm.StartVisualizer(myMeshToSimplify_HalfEdge, maxEdgesToContract: 2450, maxError: Mathf.Infinity); }
void ChangeMesh(int index) { // plane mesh if (index == 0) { myMesh1.gameObject.SetActive(true); if ((int)resolution.GetSliderValue() != myMesh1.N) { myMesh1.ResetMesh((int)resolution.GetSliderValue()); } myCylinder.gameObject.SetActive(false); myMesh = myMesh1; selectedObj = null; selectedAxis = null; axisFrame.SetActive(false); MainCamera.transform.localPosition = new Vector3(0, 1.76f, -2); } // cylinder else { myMesh1.gameObject.SetActive(false); myCylinder.gameObject.SetActive(true); selectedObj = null; selectedAxis = null; axisFrame.SetActive(false); MainCamera.transform.localPosition = new Vector3(0, 1.76f, -5.5f); } }
public unsafe bool SetTextureVertices(IMesh maxMesh, MyMesh myMesh) { bool countChanged = false; if (maxMesh.NumTVerts != myMesh.NumTextureCoordinates) { maxMesh.SetNumTVerts(myMesh.NumTextureCoordinates, false); countChanged = true; } IntPtr p3h = maxMesh.GetTVertPtr(0).NativePointer; float* p3 = (float*)p3h.ToPointer(); int elementsPerVertex = myMesh.TextureCoordinates.Count / myMesh.NumTextureCoordinates; switch (elementsPerVertex) { case 2: for (int i = 0; i < myMesh.NumTextureCoordinates; i++) { p3[(i * 3) + 0] = myMesh.TextureCoordinates[(i * 2) + 0]; p3[(i * 3) + 1] = myMesh.TextureCoordinates[(i * 2) + 1]; p3[(i * 3) + 2] = 0.0f; }; break; case 3: Marshal.Copy(myMesh.TextureCoordinates.ToArray(), 0, p3h, myMesh.NumTextureCoordinates * 3); break; default: throw new NotImplementedException(("Unable to handle texture coordinates with " + elementsPerVertex + " elements.")); } return countChanged; }
public void UpdateActiveMesh() { mActiveMesh = mWorld.GetActiveMesh(); mMeshController.SetSelectedMesh(mActiveMesh); mMeshController.ObjectSetSliders(mActiveMesh.xSize, mActiveMesh.ySize, mActiveMesh.mType); }
// Use this for initialization void Start() { Debug.Assert(MainCamera != null); Debug.Assert(lookAtObj != null); Debug.Assert(resolution != null); Debug.Assert(myMesh1 != null); Debug.Assert(myCylinder != null); Debug.Assert(axisFrame != null); Debug.Assert(axisFrame2 != null); Debug.Assert(yellowMat != null); Debug.Assert(dropdown != null); camDir = (lookAtObj.transform.localPosition - MainCamera.transform.localPosition).normalized; distance = (MainCamera.transform.localPosition - lookAtObj.transform.localPosition).magnitude; zVal = MainCamera.transform.localPosition.z; resolution.SetSliderLabel("Resolution"); resolution.TheSlider.wholeNumbers = true; resolution.TheSlider.minValue = 2; resolution.TheSlider.maxValue = 20; resolution.SetSliderValue(2); resolution.SetSliderListener(ResolutionChanged); dropdown.onValueChanged.AddListener(ChangeMesh); oldPos = Input.mousePosition; newPos = Input.mousePosition; axisFrame.SetActive(false); axisFrame2.SetActive(false); myMesh = myMesh1; myMesh1.gameObject.SetActive(true); myCylinder.gameObject.SetActive(false); MainCamera.transform.localPosition = new Vector3(0, 1.76f, -2); }
/// <summary> /// takes a single set of vertices and transforms it into a set of faces describing the face joining the 2wires contained inside the set /// </summary> /// <param name="face1">first face</param> /// <param name="face2">second face</param> /// <param name="orientation">orientation of the face</param> /// <returns>a set of faces</returns> public List <Face> ComputeFaces(Face face1, Face face2, TopAbs_Orientation orientation) { // let's compose the face between those 2 faces List <Face> subFaces = new List <Face>(); int limit = Math.Min(face1.pts.Count - 1, face2.pts.Count - 1); for (int i = 0; i < limit; i++) { Face tempFace = new Face(); tempFace.Add(face1.pts[i]); tempFace.Add(face1.pts[i + 1]); tempFace.Add(face2.pts[i + 1]); tempFace.Add(face2.pts[i]); tempFace.orientation = orientation; subFaces.Add(tempFace); } Face temp = new Face(); temp.Add(face1.pts[limit]); temp.Add(face1.pts[0]); temp.Add(face2.pts[0]); temp.Add(face2.pts[limit]); temp.orientation = orientation; subFaces.Add(temp); mesh = new MyMesh(subFaces); return(subFaces); }
// Use this for initialization void Start() { MyMesh = (MyMesh)FindObjectOfType(typeof(MyMesh)); cMesh = (CylinderMesh)FindObjectOfType(typeof(CylinderMesh)); Vertex = MyMesh.mSelected; MainController = (MainController)FindObjectOfType(typeof(MainController)); }
public MaterialWrapper(Material material, MyMesh mesh) { this.source_material = material; this.source_mesh = mesh; this.MaterialName = source_material.MaterialName; //because we need to pass it by ref later on. Initialise(); }
// Start is called before the first frame update void Start() { myMesh = GameObject.FindGameObjectWithTag("MyMesh"); meshScript = myMesh.GetComponent <MyMesh>(); //Initialize axes to disabled ToggleAxes(false); }
public Mesh CreateMesh(MyMesh MeshData) { //UpdateMeshesOnThread (); Mesh NewMesh = new Mesh (); MeshData.UpdateMeshWithData(NewMesh, null, true); return NewMesh; }
public Copter(MyMesh copterMesh, ITexture rotorTex, ITexture rotorShadow) { stCopterPos = new TPoint2(400, 200); fCopterAngle = 0f; CopterMesh = copterMesh; RotorTex = rotorTex; RotorShadow = rotorShadow; vint_dim = new TPoint2(400f, 400f); }
public void UpdateMeshesOnThread(MyMesh MeshData, Blocks MyBlocks) { if (!IsUpdatingMesh) { IsUpdatingMesh = true; UnityThreading.ActionThread NewThread = UnityThreadHelper.CreateThread(() => { // thread processing GenerateAllMeshes(MeshData, MyBlocks); }); } }
public override MyMeshMaterial GetMaterial(MyMesh mesh) { if (m_meshMaterial == null) { return(base.GetMaterial(mesh)); } m_meshMaterial.PreloadTexture(); return(m_meshMaterial); }
// public TextMesh keywordDisplay; // const int POINT_SIZE_EACH_CLUSTER = 63; public Cluster() { pos = new Vector3(); // indicesOfPoints = new int[POINT_SIZE_EACH_CLUSTER]; indicesOfPoints = new List <int>(); keywords = new List <KeyWord> (); color_score = 0; mm = new MyMesh(); }
//Display a mesh, which is called from the coroutine when a mesh has changed public void DisplayMesh(HashSet <HalfEdgeFace3> meshDataUnNormalized, MeshFilter mf) { //Generate a mesh MyMesh myMesh = HalfEdgeData3.ConvertToMyMesh("Main visualization mesh", meshDataUnNormalized, MyMesh.MeshStyle.HardEdges); Mesh mesh = myMesh.ConvertToUnityMesh(generateNormals: true); mf.mesh = mesh; //Debug.Log(mesh.triangles.Length); }
/// <summary> /// translate the element /// </summary> /// <param name="pt">the vector for the translation</param> public void Translate(Pnt pt) { for (int i = 0; i < myFaces.Count; i++) { for (int j = 0; j < myFaces[i].pts.Count; j++) { myFaces[i].pts[j] = myFaces[i].pts[j] + pt; } } mesh = new MyMesh(myFaces); }
protected Dictionary<string, IINode> CreateSkeleton_BoneSys(MyMesh mesh) { Dictionary<string, IINode> skeleton = new Dictionary<string, IINode>(); foreach (MyBone bone in mesh.Skeleton.Bones) { skeleton.Add(bone.Name, CreateBone(bone)); } return skeleton; }
// Use this for initialization void Awake() { Debug.Assert(mCamera != null); Debug.Assert(mWorld != null); Debug.Assert(mMeshController != null); Debug.Assert(mXFormController != null); mCamera4RayCast = mCamera.GetComponent <Camera>(); mActiveMesh = mWorld.GetActiveMesh(); mMeshController.SetSelectedMesh(mActiveMesh); // quad mXFormController.SetSelectedObject(mWorld.GetQuad()); }
//--------------------------------------------------------------------------------- // new object selected public void SetSelectedObject(MyMesh g) { mSelected = g; mPreviousSliderValues = Vector3.zero; /*if (g != null) * ObjectName.text = "Selected:" + g.name; * else * ObjectName.text = "Selected: none";*/ ObjectName.text = "Selected: Texture"; ObjectSetUI(); }
public void UpdateMeshAnimation(IINode node, MyMesh mesh) { switch (mesh.AnimationType) { case AnimationType.None: break; case AnimationType.Keyframes: UpdateMeshAnimation((node.ObjectRef as ITriObject), mesh.Keyframes); break; case AnimationType.PointCache: UpdateMeshAnimation_PointCache(node, mesh.Keyframes); break; } }
public unsafe void RemoveFacesByMaterialId(MyMesh myMesh, int materialId) { TriangulateFaces(myMesh); List<MyFace> filteredFaces = new List<MyFace>(myMesh.TriangulatedFaces.Length); foreach (MyFace f in myMesh.TriangulatedFaces) { if (f.MaterialId != materialId) { filteredFaces.Add(f); } } myMesh.TriangulatedFaces = filteredFaces.ToArray(); }
public bool SetPositionVertices(IMesh maxMesh, MyMesh myMesh) { bool countChanged = false; if (maxMesh.NumVerts != myMesh.NumVertices) { maxMesh.SetNumVerts(myMesh.NumVertices, false, false); countChanged = true; } IPoint3 p3 = maxMesh.GetVertPtr(0); Marshal.Copy(myMesh.Vertices.ToArray(), 0, p3.NativePointer, myMesh.NumVertices * 3); return countChanged; }
protected Dictionary<string, IINode> CreateSkeleton(MyMesh mesh) { Dictionary<string, IINode> skeleton = new Dictionary<string, IINode>(); foreach (MyBone bone in mesh.Skeleton.Bones) { IObject bone_obj = gi.COREInterface.CreateInstance(SClass_ID.Geomobject, gi.Class_ID.Create((uint)BuiltInClassIDA.BONE_OBJ_CLASSID, (uint)BuiltInClassIDB.BONE_OBJ_CLASSID)) as IObject; IINode bone_node = gi.COREInterface.CreateObjectNode(bone_obj); bone_node.Name = bone.Name; skeleton.Add(bone.Name, bone_node); } return skeleton; }
/// <summary> /// triangulate using the opencascade's triangulation /// </summary> /// <param name="shape">input shape</param> /// <param name="deflection">parameter to define the maximum angle</param> /// <returns>a list of faces</returns> public List <Face> Triangulation(TopoDS_Shape shape, double deflection) { List <Face> faces = new List <Face>(); BRepMesh.BRepMesh_IncrementalMesh im = new BRepMesh.BRepMesh_IncrementalMesh(shape, deflection); // 0.7 it controls the number of triangles im.Perform(); if (im.IsDone()) { for (TopExp_Explorer aFaceExplorer = new TopExp_Explorer(im.Shape(), TopAbs_ShapeEnum.TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) { TopoDS_Face face = TopoDS.TopoDS.ToFace(aFaceExplorer.Current()); TopLoc.TopLoc_Location L = new TopLoc.TopLoc_Location(); Poly_Triangulation tri = BRep.BRep_Tool.Triangulation(face, ref L); bool isDone = true; if (isDone) { Poly_Array1OfTriangle triangles = tri.Triangles(); TColgp_Array1OfPnt nodes = tri.Nodes(); for (int i = tri.Triangles().Lower(); i < tri.Triangles().Upper() + 1; i++) { Poly_Triangle triangle = triangles.Value(i); int node1 = 0, node2 = 0, node3 = 0; triangle.Get(ref node1, ref node2, ref node3); gp_Pnt v1 = nodes.Value(node1); gp_Pnt v2 = nodes.Value(node2); gp_Pnt v3 = nodes.Value(node3); // don't forget about face orientation :) Face f = new Face(new List <gp_Pnt> { v1, v2, v3 }) { orientation = face.Orientation() }; faces.Add(f); } } } } mesh = new MyMesh(faces); return(faces); }
protected void CreateSkinning(IINode mesh, MyMesh myMesh, Dictionary<string, IINode> skeletonMap) { IModifier skin_modifier = GetSkinModifier(mesh); IISkinImportData skin = skin_modifier.GetInterface((InterfaceID)InterfaceIDs.I_SKINIMPORTDATA) as IISkinImportData; foreach (var bone in skeletonMap.Values) { skin.AddBoneEx(bone, false); } mesh.EvalWorldState(0, true); //must be called after adding bones, but before adding weights (presumably so that something in the graph realises the bones have been added when the weights need them List<vertexWeightMap> vertexWeights = GetWeightMapsByVertex(myMesh, skeletonMap); for (int i = 0; i < vertexWeights.Count; i++) { skin.AddWeights(mesh, i, vertexWeights[i].GetBonesITab(), vertexWeights[i].GetWeightsITab()); } }
void CheckMouseClick() { if (Input.GetMouseButtonDown(0)) { RaycastHit hitInfo = new RaycastHit(); bool hit = Physics.Raycast(MainCamera.ScreenPointToRay(Input.mousePosition), out hitInfo, Mathf.Infinity, 1); if (hit && !EventSystem.current.IsPointerOverGameObject()) { MyMesh.SelectVertex(hitInfo.transform.gameObject); } else { if (axis) { DestroyImmediate(axis.gameObject); } } } }
public unsafe void TriangulateFaces(MyMesh myMesh) { if (myMesh.TriangulatedFaces != null){ return; } MyFace[] quadFaces = BlockCast(myMesh.Faces); List<MyFace> triangulatedFaces = new List<MyFace>(); foreach (MyFace f in quadFaces) { MyFace f1; f1.PositionVertex1 = f.PositionVertex1; f1.PositionVertex2 = f.PositionVertex2; f1.PositionVertex3 = f.PositionVertex3; f1.PositionVertex4 = -1; f1.TextureVertex1 = f.TextureVertex1; f1.TextureVertex2 = f.TextureVertex2; f1.TextureVertex3 = f.TextureVertex3; f1.TextureVertex4 = -1; f1.MaterialId = f.MaterialId; triangulatedFaces.Add(f1); if (f.PositionVertex4 >= 0) { MyFace f2; f2.PositionVertex1 = f.PositionVertex1; f2.PositionVertex2 = f.PositionVertex3; f2.PositionVertex3 = f.PositionVertex4; f2.PositionVertex4 = -1; f2.TextureVertex1 = f.TextureVertex1; f2.TextureVertex2 = f.TextureVertex3; f2.TextureVertex3 = f.TextureVertex4; f2.TextureVertex4 = -1; f2.MaterialId = f.MaterialId; triangulatedFaces.Add(f2); } } myMesh.TriangulatedFaces = triangulatedFaces.ToArray(); }
public unsafe bool SetFaces(IMesh maxMesh, MyMesh myMesh) { bool countChanged = false; TriangulateFaces(myMesh); if (maxMesh.NumFaces != myMesh.TriangulatedFaces.Length) { maxMesh.SetNumFaces(myMesh.TriangulatedFaces.Length, false, false); maxMesh.SetNumTVFaces(myMesh.TriangulatedFaces.Length, false, 0); countChanged = true; } /* Get the default flags value */ IFace referenceFace = gi.Face.Create(); referenceFace.SetEdgeVisFlags(EdgeVisibility.Vis, EdgeVisibility.Vis, EdgeVisibility.Vis); Face referenceMaxFace = *(Face*)referenceFace.NativePointer.ToPointer(); UInt32 referenceFlags = referenceMaxFace.flags; /* Create the faces that define the surface of the mesh */ Face* faces = (Face*)maxMesh.Faces[0].NativePointer.ToPointer(); TVFace* tvfaces = (TVFace*)maxMesh.TvFace[0].NativePointer.ToPointer(); for (int i = 0; i < myMesh.TriangulatedFaces.Length; i++) { MyFace myFace = myMesh.TriangulatedFaces[i]; faces[i].v.v1 = (UInt32)myFace.PositionVertex1; faces[i].v.v2 = (UInt32)myFace.PositionVertex2; faces[i].v.v3 = (UInt32)myFace.PositionVertex3; faces[i].flags = (UInt32)((ushort)myFace.MaterialId << 16) | (ushort)referenceFlags; tvfaces[i].t1 = (UInt32)myFace.TextureVertex1; tvfaces[i].t2 = (UInt32)myFace.TextureVertex2; tvfaces[i].t3 = (UInt32)myFace.TextureVertex3; }; return countChanged; }
/*public void ClearTerrain(Blocks MyBlocks) { for (int i = 0; i < MyBlocks.Size.x; i++) for (int j = 0; j < MyBlocks.Size.y; j++) for (int k = 0; k < MyBlocks.Size.z; k++) { MyBlocks.ClearBlockMesh(new Vector3(i,j,k)); } }*/ public void GenerateAllMeshes(MyMesh MeshData, Blocks MyBlocks) { //CreateSunlight (); MeshData.ClearMesh (); if (!IsSmoothTerrain) { // Just want to update any blocks that were changed and its surrounding ones // MyBlocks class keeps the mesh data stored in memory rather then remaking the meshes every time if (IsSubDivided) { //CreateMeshFromBlocksSubdivision (DefaultSubDivisionLevel); } else { CreateMeshFromBlocks (MyBlocks, MeshData); } for (int i = 0; i < MyBlocks.Size.x; i++) for (int j = 0; j < MyBlocks.Size.y; j++) for (int k = 0; k < MyBlocks.Size.z; k++) { if (MyBlocks.GetBlockType(new Vector3(i,j,k)) != 0) { MeshData.Add (MyBlocks.GetBlock(new Vector3(i,j,k)).GetBlockMesh()); } } CanUpdateMesh = true; } else { //CreateSmoothTerrain (); //UpdateMesh (); } }
public virtual MyMeshMaterial GetMaterial(MyMesh mesh) { MyMeshMaterial material = mesh.Materials[MaterialIndex]; material.EmissivityEnabled = m_enableEmissivity; //Preload needs to be here because of reloadcontent material.PreloadTexture(LoadingMode.Background); return material; }
public override MyMeshMaterial GetMaterial(MyMesh mesh) { if (m_meshMaterial == null) return base.GetMaterial(mesh); m_meshMaterial.PreloadTexture(); return m_meshMaterial; }
//Called from editor script public void GenerateHull() { //Get random points in 3d space HashSet <Vector3> points_Unity = TestAlgorithmsHelpMethods.GenerateRandomPoints3D(seed, halfMapSize, numberOfPoints); //HashSet<Vector3> points_Unity = GetCubeTestPoints(); //Points from a mesh /* * Transform meshTrans = constructHullFromThisMesh.transform; * * List<Vector3> vertices = new List<Vector3>(constructHullFromThisMesh.sharedMesh.vertices); * * //Local to global space * List<Vector3> verticesGlobal = vertices.Select(x => meshTrans.TransformPoint(x)).ToList(); * * HashSet<Vector3> points_Unity = new HashSet<Vector3>(verticesGlobal); */ //To stress-test these algorithms, generate points on a sphere because all of those should be on the hull //HashSet<Vector3> points_Unity = TestAlgorithmsHelpMethods.GenerateRandomPointsOnSphere(seed, radius: 1f, numberOfPoints); //To MyVector3 HashSet <MyVector3> points = new HashSet <MyVector3>(points_Unity.Select(x => x.ToMyVector3())); //Normalize Normalizer3 normalizer = new Normalizer3(new List <MyVector3>(points)); HashSet <MyVector3> points_normalized = normalizer.Normalize(points); // // Generate the convex hull // //Algorithm 1. Iterative algorithm System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); HalfEdgeData3 convexHull_normalized = _ConvexHull.Iterative_3D(points_normalized, removeUnwantedTriangles, normalizer); timer.Stop(); Debug.Log($"Generated a 3d convex hull in {timer.ElapsedMilliseconds / 1000f} seconds with {convexHull_normalized.faces.Count} triangles"); // // Display // //Points //TestAlgorithmsHelpMethods.DisplayPoints(points_Unity, 0.01f, Color.black); //Hull mesh if (convexHull_normalized != null) { HalfEdgeData3 convexHull = normalizer.UnNormalize(convexHull_normalized); MyMesh myMesh = convexHull.ConvertToMyMesh("convex hull", MyMesh.MeshStyle.HardEdges); //To unity mesh Mesh convexHullMesh = myMesh.ConvertToUnityMesh(generateNormals: false, myMesh.meshName); //Using gizmos to display mesh in 3d space gives a bad result //TestAlgorithmsHelpMethods.DisplayMeshWithRandomColors(convexHullMesh, 0); //Better to add it to a gameobject //Use Shaded Wireframe to see the triangles meshFilter.mesh = convexHullMesh; //Points on the hull //These are shining thorugh the mesh //TestAlgorithmsHelpMethods.DisplayMeshCorners(convexHullMesh, 0.01f, Color.black); } }
/*public void CreateMeshFromBlocksSubdivision(int SubDivisionLevel) { // example im coding for is 2 ClearMeshes (); TerrainMesh.FaceCount = 0; //customMesh.ClearMesh(); Debug.Log ("Adding Cubes as Models."); CubeCount = 0; float MaxSize = MyBlocks.Size.x; if (MaxSize < MyBlocks.Size.y) MaxSize = MyBlocks.Size.y; if (MaxSize < MyBlocks.Size.z) MaxSize = MyBlocks.Size.z; if (MaxSize % 2 == 1) MaxSize += 1; float MaxX = MaxSize; //MyBlocks.Size.x-(Mathf.RoundToInt(MyBlocks.Size.x) % SubDivisionLevel); float MaxY = MaxSize; //MyBlocks.Size.y-(Mathf.RoundToInt(MyBlocks.Size.y) % SubDivisionLevel); float MaxZ = MaxSize; //MyBlocks.Size.z-(Mathf.RoundToInt(MyBlocks.Size.z) % SubDivisionLevel); Debug.LogError ("MaxX: " + MaxX + " : MaxY: " + MaxY + " : MaxZ: " + MaxZ); for (int i = 0; i < MaxX; i += SubDivisionLevel) for (int j = 0; j < MaxY; j += SubDivisionLevel) for (int k = 0; k < MaxZ; k += SubDivisionLevel) { MyBlocks.GetBlockMesh(new Vector3(i,j,k)).ClearMesh (); int NewBlockType = GetBlockTypeInGroup(i, j, k, SubDivisionLevel); //Debug.LogError ("At block: " + i + ": j: " + j + ":k:" + k + " BlockType: " + NewBlockType); if (NewBlockType > 0) { // if no mesh create a mesh //if (MyBlocks.GetBlock(new Vector3(i,j,k)).HasChanged) { // if no mesh create a mesh MyBlocks.GetBlock(new Vector3(i,j,k)).HasChanged = false; CubeCount++; //Debug.Log ("Adding Cube number: " + CubeCount + " Pos: " + i + " : " + j + " : " + k); bool IsFrontFace = false; bool IsBackFace = false; bool IsLeftFace = false; bool IsRightFace = false; bool IsTopFace = false; bool IsBottomFace = false; // the bug is definitely here in the culling //if (i+SubDivisionLevel <= MaxX) if (!IsBlockInGroup(i+SubDivisionLevel+1,j,k,SubDivisionLevel)) // should be something that searches the chunk, then searches the world which is referenced in chunk IsRightFace = true; //if (i-SubDivisionLevel >= 0) if (!IsBlockInGroup(i-SubDivisionLevel-1,j,k,SubDivisionLevel)) IsLeftFace = true; //if (k+SubDivisionLevel <= MaxZ) if (!IsBlockInGroup(i,j,k+SubDivisionLevel+1,SubDivisionLevel)) IsFrontFace = true; //if (k-SubDivisionLevel >= 0) if (!IsBlockInGroup(i,j,k-SubDivisionLevel-1,SubDivisionLevel)) IsBackFace = true; //if (j+SubDivisionLevel <=MaxY) if (!IsBlockInGroup(i,j+SubDivisionLevel+1,k,SubDivisionLevel)) IsTopFace = true; //if (j-SubDivisionLevel >= 0) if (!IsBlockInGroup(i,j-SubDivisionLevel-1,k,SubDivisionLevel)) IsBottomFace = true; IsLeftFace = true; IsRightFace = true; IsBottomFace = true; IsTopFace = true; IsBackFace = true; // this one faces cam IsFrontFace = true; Vector3 TemporaryCubeSize = new Vector3(CubeSize.x*SubDivisionLevel, CubeSize.y*SubDivisionLevel,CubeSize.z*SubDivisionLevel); Vector3 NewCubePosition = new Vector3 (((float)(i)) * TemporaryCubeSize.x/((float)SubDivisionLevel), ((float)(j)) * TemporaryCubeSize.y/((float)SubDivisionLevel), ((float)(k)) * TemporaryCubeSize.z/((float)SubDivisionLevel)); //MyBlocks.Data [i].Data [j].Data [k].BlockMesh.FaceCount = TerrainMesh.FaceCount; // has to correspond to its positioning in the mesh int TileIndex = NewBlockType; //MyBlocks.GetBlockType (new Vector3(i,j,k)); //TileIndex = 2; Vector2 TilesPosition = new Vector2(); // Every Column TilesPosition.x = (TileIndex % MaxTiles); // 4 = 3,1 - 5 = 2,1 - 6 = 1,1 - 7 = 0,1 // Every Row TilesPosition.y = (TileIndex / MaxTiles); // 4 - 1 = 5 - 1 //Debug.LogError ("Now updating with tile index: " + TileIndex + " : At TilePosition: " + TilesPosition.ToString()); MyBlocks.GetBlockMesh(new Vector3(i,j,k)).CreateCube (NewCubePosition, TemporaryCubeSize, IsFrontFace, IsBackFace, IsLeftFace, IsRightFace, IsTopFace, IsBottomFace, TilesPosition, new Color32(255,255,255,255)); // MyBlocks.Data[i].Data[j].Data[k].MyColor); //MyBlocks.Data [i].Data [j].Data [k].BlockMesh.FaceCount -= TerrainMesh.FaceCount; //TerrainMesh.FaceCount += MyBlocks.Data [i].Data [j].Data [k].BlockMesh.FaceCount; //TerrainMesh.Add (MyBlocks.Data [i].Data [j].Data [k].BlockMesh); } else { //Debug.LogError ("At block: " + i + ": j: " + j + ":k:" + k + " BlockType: " + NewBlockType); } } }*/ // creates the mesh - should keep track of the mesh public void CreateMeshFromBlocks(Blocks MyBlocks, MyMesh TerrainMesh) { TerrainMesh.FaceCount = 0; for (int i = 0; i < MyBlocks.Size.x; i++) for (int j = 0; j < MyBlocks.Size.y; j++) for (int k = 0; k < MyBlocks.Size.z; k++) { //MyBlocks.Data [i].Data [j].Data [k].BlockMesh.ClearMesh (); //if (MyBlocks.Data [i].Data [j].Data [k].Type != 0) if (MyBlocks.GetBlock(new Vector3(i,j,k)).HasChanged()) { //has no mesh create a mesh MyBlocks.ClearBlockMesh(new Vector3(i,j,k)); //Debug.Log ("Adding Cube number: " + CubeCount + " Pos: " + i + " : " + j + " : " + k); bool IsFrontFace = false; bool IsBackFace = false; bool IsLeftFace = false; bool IsRightFace = false; bool IsTopFace = false; bool IsBottomFace = false; if (i != MyBlocks.Size.x - 1) if (MyBlocks.GetBlockType (new Vector3 (i + 1, j, k)) == 0) // should be something that searches the chunk, then searches the world which is referenced in chunk IsRightFace = true; if (i != 0) if (MyBlocks.GetBlockType (new Vector3 (i - 1, j, k)) == 0) IsLeftFace = true; if (k != MyBlocks.Size.z - 1) // if not on edge if (MyBlocks.GetBlockType (new Vector3 (i, j, k + 1)) == 0) IsFrontFace = true; if (k != 0) if (MyBlocks.GetBlockType (new Vector3 (i, j, k - 1)) == 0) IsBackFace = true; if (j != MyBlocks.Size.y - 1) if (MyBlocks.GetBlockType (new Vector3 (i, j + 1, k)) == 0) IsTopFace = true; if (j != 0) if (MyBlocks.GetBlockType (new Vector3 (i, j - 1, k)) == 0) IsBottomFace = true; if (i == 0) IsLeftFace = true; if (i == MyBlocks.Size.x - 1) IsRightFace = true; if (j == 0) IsBottomFace = true; if (j == MyBlocks.Size.y - 1) IsTopFace = true; if (k == 0) IsBackFace = true; if (k == MyBlocks.Size.z - 1) IsFrontFace = true; Vector3 NewCubePosition = new Vector3 (((float)(i)) * MyBlocks.Scale.x, ((float)(j)) * MyBlocks.Scale.y, ((float)(k)) * MyBlocks.Scale.z); //MyBlocks.Data [i].Data [j].Data [k].BlockMesh.FaceCount = TerrainMesh.FaceCount; int TileIndex = MyBlocks.GetBlockType (new Vector3(i,j,k)); //TileIndex = 2; Vector2 TilesPosition = new Vector2(); // Every Column TilesPosition.x = (TileIndex % TileMapLength); // 4 = 3,1 - 5 = 2,1 - 6 = 1,1 - 7 = 0,1 // Every Row TilesPosition.y = (TileIndex / TileMapLength); // 4 - 1 = 5 - 1 //Debug.LogError ("Now updating with tile index: " + TileIndex + " : At TilePosition: " + TilesPosition.ToString()); MyBlocks.GetBlockMesh(new Vector3(i,j,k)).CreateCube (NewCubePosition, MyBlocks.Scale, IsFrontFace, IsBackFace, IsLeftFace, IsRightFace, IsTopFace, IsBottomFace, TilesPosition, new Color32(255,255,255,255)); // MyBlocks.Data[i].Data[j].Data[k].MyColor); } } }
public void UpdateMesh(MyMesh NewMesh){ MeshFilter NewMeshFilter = gameObject.GetComponent<MeshFilter>(); if (NewMeshFilter != null) { NewMesh.UpdateMeshWithData(NewMeshFilter.mesh, gameObject.GetComponent<MeshCollider>(), true); } }
public void Add(MyMesh AddMesh) { if (AddMesh != null) { int VertexBuffer = Verticies.Count; for (int i = 0; i < AddMesh.Verticies.Count; i++) Verticies.Add (AddMesh.Verticies [i]); for (int i = 0; i < AddMesh.Indicies.Count; i++) { Indicies.Add (VertexBuffer+AddMesh.Indicies [i]); } for (int i = 0; i < AddMesh.TextureCoordinates.Count; i++) TextureCoordinates.Add (AddMesh.TextureCoordinates [i]); for (int i = 0; i < AddMesh.TextureCoordinates.Count; i++) Colors.Add (AddMesh.Colors [i]); } }
/* See this Max documentation page on how to build a mesh: http://docs.autodesk.com/3DSMAX/16/ENU/3ds-Max-SDK-Programmer-Guide/index.html?url=files/GUID-714885D1-B3D4-4F64-8EE5-0B22B689C95B.htm,topicNumber=d30e53726 */ public void UpdateMesh(IMesh maxMesh, MyMesh myMesh) { bool countChanged = false; countChanged = SetPositionVertices(maxMesh, myMesh); //if the mesh is new or has been significantly altered, recreate the whole topology if (countChanged) { SetTextureVertices(maxMesh, myMesh); SetFaces(maxMesh, myMesh); maxMesh.EnableEdgeList(1); SmoothMesh(maxMesh, myMesh); } maxMesh.InvalidateGeomCache(); maxMesh.InvalidateTopologyCache(); }
public void SmoothMesh(IMesh maxMesh, MyMesh myMesh) { //todo: get angle from material for smoothing maxMesh.AutoSmooth((float)DegreeToRadian(30.0), false, true); }
public void AddQuadTextureFace(MyMesh MyCustomMesh, Vector2 TextureUnit) { float TextureSize = 1f / 8f; TextureUnit.x = TextureUnit.x / 8f; TextureUnit.y = TextureUnit.y / 8f; MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x + TextureSize, TextureUnit.y)); MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x + TextureSize, TextureUnit.y+TextureSize)); MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x, TextureUnit.y)); MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x+TextureSize, TextureUnit.y+TextureSize)); MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x, TextureUnit.y+TextureSize)); MyCustomMesh.TextureCoordinates.Add (new Vector2 (TextureUnit.x, TextureUnit.y)); }
protected IEnumerable<MaterialWrapper> GetMaterials(MyMesh myMesh) { foreach (var myMat in myMesh.Materials) { yield return new MaterialWrapper(myMat, myMesh); } }
public BlockModel(Mesh NewMesh) { Initialize (); IsMultipleTextureMaps = false; BlockMeshes [0] = new MyMesh (NewMesh); }
public Copter(MyMesh copterMesh, ITexture rotorTex, ITexture rotorShadow) { stCopterPos = new TPoint2(400, 200); fCopterAngle = 0f; CopterMesh = copterMesh; RotorTex = rotorTex; RotorShadow = rotorShadow; vint_dim = new TPoint2(400f, 400f); }
public Mesh[] LoadJSONFileAsync(string fileName) { string data = System.IO.File.ReadAllText(fileName); var meshes = new List <Mesh>(); JToken jtoken = Newtonsoft.Json.JsonConvert.DeserializeObject(data) as JToken; MyMeshCollection myMesh = jtoken.ToObject <MyMeshCollection>(); List <Mesh> meshList = new List <Mesh>(); List <MyMaterial> materials = myMesh.materials; Dictionary <string, MyMaterial> material_dic = new Dictionary <string, MyMaterial>(); int meshCount = myMesh.meshes.Count; for (int materialIndex = 0; materialIndex < materials.Count; materialIndex++) { MyMaterial myMaterial = materials[materialIndex]; if (myMaterial.diffuseTexture != null) { myMaterial.DiffuseTextureName = (myMaterial.diffuseTexture.name); } material_dic.Add(myMaterial.id, myMaterial); } for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex) { MyMesh mymesh = myMesh.meshes[meshIndex]; double[] verticesArray = mymesh.vertices; int[] indicesArray = mymesh.indices; double[] position = mymesh.position; int uvCount = mymesh.uvCount; int verticesStep = 1; switch (uvCount) { case 0: verticesStep = 6; break; case 1: verticesStep = 8; break; case 2: verticesStep = 10; break; } // the number of interesting vertices information for us int verticesCount = verticesArray.Length / verticesStep; // number of faces is logically the size of the array divided by 3 (A, B, C) int facesCount = indicesArray.Length / 3; Mesh mesh = new Mesh(mymesh.name, verticesCount, facesCount); meshList.Add(mesh); // Filling the Vertices array of our mesh first for (var index = 0; index < verticesCount; index++) { double x = verticesArray[index * verticesStep]; double y = verticesArray[index * verticesStep + 1]; double z = verticesArray[index * verticesStep + 2]; // Loading the vertex normal exported by Blender double nx = verticesArray[index * verticesStep + 3]; double ny = verticesArray[index * verticesStep + 4]; double nz = verticesArray[index * verticesStep + 5]; if (uvCount > 0) { // Loading the texture coordinates double u = verticesArray[index * verticesStep + 6]; double v = verticesArray[index * verticesStep + 7]; mesh.Vertices[index] = new Vertex { Coordinates = new Vector3d(x, y, z), Normal = new Vector3d(nx, ny, nz), TextureCoordinates = new Vector2d(u, v) }; } else { //no uv mesh.Vertices[index] = new Vertex { Coordinates = new Vector3d(x, y, z), Normal = new Vector3d(nx, ny, nz) }; } } // Then filling the Faces array for (var index = 0; index < facesCount; index++) { int a = indicesArray[index * 3]; int b = indicesArray[index * 3 + 1]; int c = indicesArray[index * 3 + 2]; mesh.Faces[index] = new Face { A = a, B = b, C = c }; } // Getting the position you've set in Blender mesh.Position = new Vector3d(position[0], position[1], position[2]); if (uvCount > 0) { // Texture string meshTextureID = mymesh.materialId; string meshTextureName = material_dic[meshTextureID].DiffuseTextureName; mesh.Texture = new Texture(meshTextureName, 512, 512); } mesh.ComputeFaceNormals(); } return(meshList.ToArray()); }
// Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time. // This loads only vertex data, doesn't touch GPU // Can be called from main and background thread public void LoadData() { if (m_loadedData) return; lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); string assetForImport = AssetName; var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName); if (!MyFileSystem.FileExists(fsPath)) { assetForImport = @"Models\Debug\Error.mwm"; } try { m_importer.ImportData(assetForImport); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); DataVersion = m_importer.DataVersion; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary<string, object> tagData = m_importer.GetTagData(); if (tagData.Count == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords"); HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES]; System.Diagnostics.Debug.Assert(vertices.Length > 0); Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS]; m_vertices = new MyCompressedVertexNormal[vertices.Length]; if (normals.Length > 0) { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v]) }; } } else { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), }; } } m_verticesCount = vertices.Length; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh"); var materials = new Dictionary<string, MyMeshMaterial>(); m_meshContainer.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS)) { List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation int maxIndex = 0; List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>; foreach (MyMeshPartInfo meshPart in meshParts) { MyMesh mesh = new MyMesh(meshPart, m_assetName); mesh.IndexStart = indices.Count; mesh.TriCount = meshPart.m_indices.Count / 3; if (mesh.Material.Name != null) materials.Add(mesh.Material.Name, mesh.Material); if (m_loadUV && false == m_hasUV) { m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; m_hasUV = true; m_loadUV = false; } if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS) { GlassData = mesh; HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; List<HalfVector2> neededTexCoords = new List<HalfVector2>(); for (int t = 0; t < meshPart.m_indices.Count; t++) { int index = meshPart.m_indices[t]; neededTexCoords.Add(forLoadingTexCoords0[index]); } GlassTexCoords = neededTexCoords.ToArray(); } System.Diagnostics.Debug.Assert(mesh.TriCount > 0); if (mesh.TriCount == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return; } foreach (var i in meshPart.m_indices) { indices.Add(i); if (i > maxIndex) { maxIndex = i; } } m_meshContainer.Add(mesh); } if (maxIndex <= ushort.MaxValue) { // create 16 bit indices m_Indices_16bit = new ushort[indices.Count]; for (int i = 0; i < indices.Count; i++) { m_Indices_16bit[i] = (ushort)indices[i]; } } else { // use 32bit indices m_Indices = indices.ToArray(); } } m_meshSections.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_SECTIONS)) { List<MyMeshSectionInfo> sections = tagData[MyImporterConstants.TAG_MESH_SECTIONS] as List<MyMeshSectionInfo>; int sectionindex = 0; foreach (MyMeshSectionInfo sectinfo in sections) { MyMeshSection section = new MyMeshSection() { Name = sectinfo.Name, Index = sectionindex }; m_meshSections.Add(section.Name, section); sectionindex++; } } if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH)) { m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data"); Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; Vector4I[] boneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES]; Vector4[] boneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS]; if (boneIndices != null && boneIndices.Length != 0) { if (boneWeights != null && boneIndices.Length == boneWeights.Length && boneIndices.Length == m_vertices.Length) { m_bonesIndicesWeights = new MyCompressedBoneIndicesWeights[boneIndices.Length]; for (int it = 0; it < boneIndices.Length; it++) { m_bonesIndicesWeights[it].Indices = new Byte4(boneIndices[it].X, boneIndices[it].Y, boneIndices[it].Z, boneIndices[it].W); m_bonesIndicesWeights[it].Weights = new HalfVector4(boneWeights[it]); } } else { Debug.Assert(false, "Bone indices/weights my be same number as vertices"); } } BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES)) ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES]; object patternScale; if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale)) { PatternScale = (float)patternScale; } if (BoneMapping.Length == 0) BoneMapping = null; if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY)) { HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized) { bool containsSceneData; bool containsDestructionData; List<HkShape> shapesList = new List<HkShape>(); if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData)) { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS); //Debug.Fail("Collision model was exported in wrong way: " + m_assetName); } if (shapesList.Count > 10) MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS); if (HavokCollisionShapes != null) { Debug.Fail("Shapes already loaded"); } if (shapesList.Count > 0) { HavokCollisionShapes = shapesList.ToArray(); } else { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName)); } if (containsDestructionData) HavokDestructionData = tagCollisionData; ExportedWrong = !containsSceneData; } } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION)) { if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0) HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices"); // Prepare data CopyTriangleIndices(); m_trianglesCount = Triangles.Length; // Remember this numbers as list may be cleared at the end of this method VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); VRageRender.Utils.Stats.PerAppLifetime.MyModelsCount++; VRageRender.Utils.Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; VRageRender.Utils.Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); VRageRender.Utils.Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length; ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); m_loadedData = true; m_loadingErrorProcessed = false; MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
// Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time. // This loads only vertex data, doesn't touch GPU // Can be called from main and background thread public void LoadData() { if (m_loadedData) { return; } lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); string assetForImport = AssetName; var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName); if (!MyFileSystem.FileExists(fsPath)) { assetForImport = @"Models\Debug\Error.mwm"; } try { m_importer.ImportData(assetForImport); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); DataVersion = m_importer.DataVersion; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary <string, object> tagData = m_importer.GetTagData(); if (tagData.Count == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords"); HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES]; System.Diagnostics.Debug.Assert(vertices.Length > 0); Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS]; m_vertices = new MyCompressedVertexNormal[vertices.Length]; if (normals.Length > 0) { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v], // VF_Packer.PackPosition(ref vertices[v]), Normal = normals[v] //VF_Packer.PackNormalB4(ref normals[v]) }; } } else { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), }; } } m_verticesCount = vertices.Length; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh"); var materials = new Dictionary <string, MyMeshMaterial>(); m_meshContainer.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS)) { List <int> indices = new List <int>(GetVerticesCount()); // Default capacity estimation int maxIndex = 0; List <MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List <MyMeshPartInfo>; foreach (MyMeshPartInfo meshPart in meshParts) { MyMesh mesh = new MyMesh(meshPart, m_assetName); mesh.IndexStart = indices.Count; mesh.TriCount = meshPart.m_indices.Count / 3; if (mesh.Material.Name != null) { materials.Add(mesh.Material.Name, mesh.Material); } if (m_loadUV && false == m_hasUV) { m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; m_hasUV = true; m_loadUV = false; } if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS) { GlassData = mesh; HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; List <HalfVector2> neededTexCoords = new List <HalfVector2>(); for (int t = 0; t < meshPart.m_indices.Count; t++) { int index = meshPart.m_indices[t]; neededTexCoords.Add(forLoadingTexCoords0[index]); } GlassTexCoords = neededTexCoords.ToArray(); } System.Diagnostics.Debug.Assert(mesh.TriCount > 0); if (mesh.TriCount == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return; } foreach (var i in meshPart.m_indices) { indices.Add(i); if (i > maxIndex) { maxIndex = i; } } m_meshContainer.Add(mesh); } if (maxIndex <= ushort.MaxValue) { // create 16 bit indices m_Indices_16bit = new ushort[indices.Count]; for (int i = 0; i < indices.Count; i++) { m_Indices_16bit[i] = (ushort)indices[i]; } } else { // use 32bit indices m_Indices = indices.ToArray(); } } m_meshSections.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_SECTIONS)) { List <MyMeshSectionInfo> sections = tagData[MyImporterConstants.TAG_MESH_SECTIONS] as List <MyMeshSectionInfo>; int sectionindex = 0; foreach (MyMeshSectionInfo sectinfo in sections) { MyMeshSection section = new MyMeshSection() { Name = sectinfo.Name, Index = sectionindex }; m_meshSections.Add(section.Name, section); sectionindex++; } } if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH)) { m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data"); Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; Vector4I[] boneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES]; Vector4[] boneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS]; if (boneIndices != null && boneIndices.Length != 0) { if (boneWeights != null && boneIndices.Length == boneWeights.Length && boneIndices.Length == m_vertices.Length) { m_bonesIndicesWeights = new MyCompressedBoneIndicesWeights[boneIndices.Length]; for (int it = 0; it < boneIndices.Length; it++) { m_bonesIndicesWeights[it].Indices = new Byte4(boneIndices[it].X, boneIndices[it].Y, boneIndices[it].Z, boneIndices[it].W); m_bonesIndicesWeights[it].Weights = new HalfVector4(boneWeights[it]); } } else { Debug.Assert(false, "Bone indices/weights my be same number as vertices"); } } BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary <string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES)) { ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES]; } object patternScale; if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale)) { PatternScale = (float)patternScale; } if (BoneMapping.Length == 0) { BoneMapping = null; } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY)) { HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized) { bool containsSceneData; bool containsDestructionData; List <HkShape> shapesList = new List <HkShape>(); if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData)) { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS); //Debug.Fail("Collision model was exported in wrong way: " + m_assetName); } if (shapesList.Count > 10) { MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS); } if (HavokCollisionShapes != null) { Debug.Fail("Shapes already loaded"); } if (shapesList.Count > 0) { HavokCollisionShapes = shapesList.ToArray(); } else { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName)); } if (containsDestructionData) { HavokDestructionData = tagCollisionData; } ExportedWrong = !containsSceneData; } } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION)) { if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0) { HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]; } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices"); // Prepare data CopyTriangleIndices(); m_trianglesCount = Triangles.Length; // Remember this numbers as list may be cleared at the end of this method VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); VRageRender.Utils.Stats.PerAppLifetime.MyModelsCount++; VRageRender.Utils.Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; VRageRender.Utils.Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); VRageRender.Utils.Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length; ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); m_loadedData = true; m_loadingErrorProcessed = false; MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
void Start() { vertices_Unity = new HashSet <UnityEngine.Vector3>(); for (int i = 0; i < pointCount; i++) { UnityEngine.Vector3 point = srcMesh.mesh.GetRandomPointInsideNonConvex(srcMesh.GetComponent <Renderer>().bounds.center); vertices_Unity.Add(point); } HashSet <Vector3> points = new HashSet <Vector3>(vertices_Unity.Select(x => x.ToMyVector3())); Normalizer3 normalizer = new Normalizer3(new List <Vector3>(points)); HashSet <Vector3> points_normalized = normalizer.Normalize(points); //Convex Hull HalfEdgeData3 convexHull_normalized = _ConvexHull.Iterative_3D(points_normalized, removeUnwantedTriangles: false, normalizer); //HalfEdgeData3 convexHull_unnormalized = _ConvexHull.Iterative_3D(points, removeUnwantedTriangles: false, normalizer); var tmp = convexHull_normalized.ConvertToMyMesh("Triangulated Points", MyMesh.MeshStyle.HardEdges); delaunayMesh = tmp.ConvertToUnityMesh(true); // if (convexHull_normalized == null) // { // Debug.LogError("ConvexHull is null"); // return; // } // HashSet <VoronoiCell3> voronoiCells_normalized = _Voronoi.Delaunay3DToVoronoi(convexHull_normalized); HalfEdgeData3 convexHull = normalizer.UnNormalize(convexHull_normalized); MyMesh myMesh = convexHull.ConvertToMyMesh("convex hull aka delaunay triangulation", MyMesh.MeshStyle.HardEdges); delaunayMesh = myMesh.ConvertToUnityMesh(generateNormals: false); //Voronoi HashSet <VoronoiCell3> voronoiCells = normalizer.UnNormalize(voronoiCells_normalized); //Generate a mesh for each separate cell voronoiCellsMeshes = GenerateVoronoiCellsMeshes(voronoiCells); foreach (var mesh in voronoiCellsMeshes) { GameObject go = new GameObject(); var meshfilter = go.AddComponent <MeshFilter>(); var renderer = go.AddComponent <MeshRenderer>(); renderer.sharedMaterial = material; meshfilter.mesh = mesh; go.transform.parent = gameObject.transform; } //Generate a single mesh for all cells where each vertex has a color belonging to that cell //Now we can display the mesh with an unlit shader where each vertex is associated with a color belonging to that cell //The problem is that the voronoi cell is not a flat surface on the mesh //But it looks flat if we are using an unlit shader // Mesh oneMesh = GenerateAndDisplaySingleMesh(voronoiCellsMeshes); // // if (meshFilter != null) // { // meshFilter.mesh = oneMesh; // } // else // { // Debug.LogError("Meshfilter is null"); // } }
/* Ideally we would create selection sets for each character so that they can be easily included/excluded from things like lighting */ //public void AddToSelectionSet(string selectionSetName, IINode node) //{ // ITab<IINode> selectionSetNodes = globalInterface.Tab.Create<IINode>(); // selectionSetNodes.Append(1, node., 0); // globalInterface.INamedSelectionSetManager.Instance.GetNamedSelSetList(selectionSetNodes, globalInterface.INamedSelectionSetManager.Instance.get // globalInterface.INamedSelectionSetManager.Instance.ReplaceNamedSelSet( //} protected void UpdateMeshData(MyMesh myMesh) { UpdateProgress(0.0f, "Getting mapped items..."); IList<IINode> mappedNodes = GetMappedNodes(myMesh.Name).ToList(); //No mesh nodes exist with that name yet, so initialise a new node for the object if (mappedNodes.Count < 1) { UpdateProgress(0.1f, "Creating object..."); mappedNodes.Add(CreateMeshNode(myMesh)); } IList<MaterialWrapper> Materials = GetMaterials(myMesh).ToList(); foreach (var m in mappedNodes) { UpdateProgress(0.2f, "Updating geometry..."); if (RemoveTransparentFaces) { foreach (var transparentMaterial in Materials.Where(ms => ms.IsTransparent)) { RemoveFacesByMaterialId(myMesh, transparentMaterial.MaterialIndex); } } UpdateMesh((m.ObjectRef as ITriObject).Mesh, myMesh); UpdateMeshAnimation(m, myMesh); UpdateMeshSkin(m, myMesh); if (RebuildMaterials) { m.Mtl = null; } if (m.Mtl == null) { UpdateProgress(0.6f, "Updating materials..."); m.Mtl = CreateMultiMaterial(Materials); } } UpdateProgress(1.0f, "Done."); }
void CreateSmoothTerrain(MyMesh TerrainMesh, MarchingCubes marchingCubes, Blocks MyBlocks) { Debug.Log ("Creating Smooth Terrain"); Vector3 BlockScale = MyBlocks.Scale; // Marching cubes is one too small! // for some reason the size has to be like this Vector3 WorldSize_ = MyBlocks.Size; int expand = 0;// WorldCore->MarchingExpand; WorldSize_.x += expand; WorldSize_.y += expand; WorldSize_.z += expand; // = 18 now out of 16 0 to 15 // I need to perform this calculation PER CUBE and not per grid // So perform calculation depending on surrounding cubes, but not whole thing //MarchingCubesData.Clear(); //for (int i = 0; i < (WorldSize_.x)*(WorldSize_.y)*(WorldSize_.z); i++) // MarchingCubesData.Add(0.0f); //marchingCubes.ClearData(MarchingCubesData); marchingCubes = new MarchingCubes(new Vector3(WorldSize_.x, WorldSize_.x, WorldSize_.x), Mathf.RoundToInt(WorldSize_.x)); marchingCubes.PolygonizeData(MyBlocks, WorldSize_); TerrainMesh.ClearMesh (); for (int i = 0; i < marchingCubes.trilist.Count; i++) { // for every triangle in list marchingCubes.trilist[i].calcnormal(true); TerrainMesh.Verticies.Add (marchingCubes.trilist[i].position[0]); TerrainMesh.Verticies.Add (marchingCubes.trilist[i].position[1]); TerrainMesh.Verticies.Add (marchingCubes.trilist[i].position[2]); TerrainMesh.Colors.Add (marchingCubes.trilist[i].colors[0]); TerrainMesh.Colors.Add (marchingCubes.trilist[i].colors[1]); TerrainMesh.Colors.Add (marchingCubes.trilist[i].colors[2]); TerrainMesh.Indicies.Add (TerrainMesh.Verticies.Count-3); TerrainMesh.Indicies.Add (TerrainMesh.Verticies.Count-2); TerrainMesh.Indicies.Add (TerrainMesh.Verticies.Count-1); } Debug.Log ("Created Smooth Terrain"); }
protected IINode CreateMeshNode(MyMesh mesh) { IMatrix3 identity = gi.Matrix3.Create(); identity.IdentityMatrix(); ITriObject meshObject = gi.CreateNewTriObject(); IINode myNode = gi.COREInterface.CreateObjectNode(meshObject); myNode.Name = mesh.Name; /* In this section we reset the transform of the node (as it may have been initialised with a rotation depending on what viewport was selected) * and rotate it with OBJECT ONLY flag set, which will set the object-offset transform which sits been the vertex position data and WSM */ myNode.SetNodeTM(0, identity); myNode.Rotate(0, identity, gi.AngAxis.Create(1.0f, 0.0f, 0.0f, (float)DegreeToRadian(-90.0f)), true, true, (int)PivotMode.PIV_OBJECT_ONLY, true); if (mesh.ParentName != null && mesh.ParentName != mesh.Name) { var parentNode = GetMappedNodes(mesh.ParentName).FirstOrDefault(); if (parentNode != null) { parentNode.AttachChild(myNode, false); } } return myNode; }
/// <summary> /// updates the instance of MyMesh with the Faces /// </summary> public void RecalculateMesh() { mesh = new MyMesh(myFaces); }
public void SimplifyMesh() { //Has to be sharedMesh if we are using Editor tools Mesh meshToSimplify = meshFilterToSimplify.sharedMesh; // // Change data structure and normalize // //Mesh -> MyMesh MyMesh myMeshToSimplify = new MyMesh(meshToSimplify); //Normalize to 0-1 Normalizer3 normalizer = new Normalizer3(myMeshToSimplify.vertices); //We only need to normalize the vertices myMeshToSimplify.vertices = normalizer.Normalize(myMeshToSimplify.vertices); HalfEdgeData3 myMeshToSimplify_HalfEdge = new HalfEdgeData3(myMeshToSimplify, HalfEdgeData3.ConnectOppositeEdges.Fast); // // Simplify // System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); HalfEdgeData3 mySimplifiedMesh_HalfEdge = MeshSimplification_QEM.Simplify(myMeshToSimplify_HalfEdge, maxEdgesToContract: 2400, maxError: Mathf.Infinity, normalizeTriangles: true); timer.Stop(); Debug.Log($"It took {timer.ElapsedMilliseconds / 1000f} seconds to simplify the mesh"); // // Change data structure and un-normalize // timer.Reset(); timer.Start(); //From half-edge to mesh MyMesh mySimplifiedMesh = mySimplifiedMesh_HalfEdge.ConvertToMyMesh("Simplified mesh", MyMesh.MeshStyle.HardEdges); //Un-Normalize mySimplifiedMesh.vertices = normalizer.UnNormalize(mySimplifiedMesh.vertices); //Convert to global space Transform trans = meshFilterToSimplify.transform; mySimplifiedMesh.vertices = mySimplifiedMesh.vertices.Select(x => trans.TransformPoint(x.ToVector3()).ToMyVector3()).ToList(); //Convert to mesh Mesh unitySimplifiedMesh = mySimplifiedMesh.ConvertToUnityMesh(generateNormals: true, meshName: "simplified mesh"); //Attach to new game object meshFilterToShowSimplifiedMesh.mesh = unitySimplifiedMesh; timer.Stop(); Debug.Log($"It took {timer.ElapsedMilliseconds / 1000f} seconds to finalize the mesh after simplifying"); }
public PointCloud(MyMesh mesh) { this.mesh = mesh; }
public void Initialize() { for (int i = 0; i < 6; i++) { BlockMeshes[i] = new MyMesh(); } }
public void SetSelectedMesh(MyMesh mesh) { mMesh = mesh; }
//Generates points, delaunay triangulation, and voronoi diagram public void Generate() { if (radius <= 0f) { radius = 0.01f; } if (numberOfPoints < 4) { numberOfPoints = 4; } //Get random points in 3d space points_Unity = TestAlgorithmsHelpMethods.GenerateRandomPointsOnSphere(seed, radius, numberOfPoints); //To MyVector3 HashSet <MyVector3> points = new HashSet <MyVector3>(points_Unity.Select(x => x.ToMyVector3())); //Normalize Normalizer3 normalizer = new Normalizer3(new List <MyVector3>(points)); HashSet <MyVector3> points_normalized = normalizer.Normalize(points); System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); // // Generate the convex hull, which is the same as the Delaunay triangulation of points on the sphere // //Iterative algorithm timer.Start(); HalfEdgeData3 convexHull_normalized = _ConvexHull.Iterative_3D(points_normalized, removeUnwantedTriangles: false, normalizer); timer.Stop(); Debug.Log($"Generated a 3d convex hull in {timer.ElapsedMilliseconds / 1000f} seconds"); if (convexHull_normalized == null) { return; } // // Generate the voronoi diagram from the delaunay triangulation // timer.Restart(); HashSet <VoronoiCell3> voronoiCells_normalized = _Voronoi.Delaunay3DToVoronoi(convexHull_normalized); timer.Stop(); Debug.Log($"Generated a 3d voronoi diagram in {timer.ElapsedMilliseconds / 1000f} seconds"); if (voronoiCells_normalized == null) { return; } // // Display // //Delaunay HalfEdgeData3 convexHull = normalizer.UnNormalize(convexHull_normalized); MyMesh myMesh = convexHull.ConvertToMyMesh("convex hull aka delaunay triangulation", MyMesh.MeshStyle.HardEdges); delaunayMesh = myMesh.ConvertToUnityMesh(generateNormals: false); //Voronoi HashSet <VoronoiCell3> voronoiCells = normalizer.UnNormalize(voronoiCells_normalized); //Generate a mesh for each separate cell voronoiCellsMeshes = GenerateVoronoiCellsMeshes(voronoiCells); //Generate a single mesh for all cells where each vertex has a color belonging to that cell //Now we can display the mesh with an unlit shader where each vertex is associated with a color belonging to that cell //The problem is that the voronoi cell is not a flat surface on the mesh //But it looks flat if we are using an unlit shader Mesh oneMesh = GenerateAndDisplaySingleMesh(voronoiCellsMeshes); if (meshFilter != null) { meshFilter.mesh = oneMesh; } }