/// Loads a MagicaVoxel model into the current model. public void LoadMagicaModel(string magicaVoxelFile, bool retainVoxels, VoxelFactory.ColliderType colliderType, MagicaFlags flags) { Clear(); this.colliderType = colliderType; PointQuadList opaqueFaces = new PointQuadList(); PointQuadList transparentFaces = new PointQuadList(); IntPtr model = OpenBoxNative.MagicaLoadModel(magicaVoxelFile, flags); OpenBoxNative.MagicaExtractFaces(model, ref opaqueFaces, ref transparentFaces); if (retainVoxels || colliderType != VoxelFactory.ColliderType.None) { // Copy voxels over to the C# side voxels = new VoxelSet <Color32>(OpenBoxNative.MagicaModelSize(model)); OpenBoxNative.MagicaCopyVoxels(voxels.Pin(), model); voxels.Unpin(); // TODO: Calculate colliders natively UpdateColliders(); } OpenBoxNative.MagicaFreeModel(model); MakeMeshFromQuadLists(opaqueFaces, transparentFaces); OpenBoxNative.FreeFacesHandle(opaqueFaces.handle); OpenBoxNative.FreeFacesHandle(transparentFaces.handle); }
/// Adds all geometry in the given quad lists to the given mesh. static int AddMeshGeometry(PointQuadList[] quads, Mesh mesh) { int geometryCount = 0; int subMeshCount = 0; foreach (var q in quads) { geometryCount += q.count; if (q.count > 0) { subMeshCount++; } } // Flatten into mesh Vector3[] points = new Vector3[geometryCount]; Color32[] colors = new Color32[geometryCount]; Vector2[] uvs = new Vector2[geometryCount]; var pointsHandle = GCHandle.Alloc(points, GCHandleType.Pinned); var colorsHandle = GCHandle.Alloc(colors, GCHandleType.Pinned); var uvsHandle = GCHandle.Alloc(uvs, GCHandleType.Pinned); int facesFilled = 0; for (int i = 0; i < quads.Length; ++i) { OpenBoxNative.CopyFaceGeometry( quads[i].handle, Marshal.UnsafeAddrOfPinnedArrayElement(points, facesFilled), Marshal.UnsafeAddrOfPinnedArrayElement(uvs, facesFilled), Marshal.UnsafeAddrOfPinnedArrayElement(colors, facesFilled) ); } pointsHandle.Free(); colorsHandle.Free(); uvsHandle.Free(); mesh.vertices = points; mesh.colors32 = colors; mesh.uv = uvs; return(subMeshCount); }
/// Turns the current voxel set into a mesh, replacing any currently attached mesh. public void UpdateMesh() { MeshFilter mf = GetComponent <MeshFilter>(); // TODO: Remove old mesh? PointQuadList opaqueFaces = new PointQuadList(); PointQuadList transparentFaces = new PointQuadList(); IntPtr voxelsPtr = voxels.Pin(); OpenBoxNative.ExtractFaces(voxelsPtr, voxels.Size, ref opaqueFaces, ref transparentFaces); voxels.Unpin(); MakeMeshFromQuadLists(opaqueFaces, transparentFaces); OpenBoxNative.FreeFacesHandle(opaqueFaces.handle); OpenBoxNative.FreeFacesHandle(transparentFaces.handle); }