// todo: remove source param public static IFlexibleModel CreateSimple(IResourceSource source, VertexPosNormTex[] vertices, int[] indices, FlexibleModelPrimitiveTopology primitiveTopology) { var pack = new ResourcePack(ResourceVolatility.Immutable); //pack.Source = source; RawDataResource vertexDataRes; fixed(VertexPosNormTex *pVertices = vertices) vertexDataRes = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pVertices, vertices.Length * sizeof(VertexPosNormTex)); pack.AddSubresource("VertexArray", vertexDataRes); var hasIndices = indices != null; RawDataResource indexDataRes = null; if (hasIndices) { fixed(int *pIndices = indices) indexDataRes = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pIndices, indices.Length * sizeof(int)); pack.AddSubresource("IndexArray", indexDataRes); } var arraySubranges = hasIndices ? new[] { vertexDataRes.GetSubrange(0), indexDataRes.GetSubrange(0) } : new[] { vertexDataRes.GetSubrange(0) }; var elementInfos = VertexPosNormTex.GetElementsInfos(0); var indicesInfo = hasIndices ? new VertexIndicesInfo(1, CommonFormat.R32_UINT) : null; var vertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable, arraySubranges, elementInfos, indicesInfo); pack.AddSubresource("VertexSet", vertexSet); var modelPart = new FlexibleModelPart { ModelMaterialName = "MainMaterial", VertexSetIndex = 0, PrimitiveTopology = primitiveTopology, IndexCount = hasIndices ? indices.Length : vertices.Length, FirstIndex = 0, VertexOffset = 0 }; var sphere = Sphere.BoundingSphere(vertices, x => x.Position); var model = new FlexibleModel(ResourceVolatility.Immutable, new[] { vertexSet }, new[] { modelPart }, sphere); pack.AddSubresource("Model", model); model.Source = source; return(model); }
private unsafe IAsset BuildAsset(AssetLoadInfo loadInfo) { var fileData = loadInfo.FileSystem.ReadAllBytes(loadInfo.LoadPath); var objLoaderFactory = new ObjLoaderFactory(); var objLoader = objLoaderFactory.Create(new MyMaterialStreamProvider(Path.GetDirectoryName(loadInfo.LoadPath), loadInfo.FileSystem)); LoadResult objLoadResult; using (var stream = new MemoryStream(fileData)) objLoadResult = objLoader.Load(stream); var anyTextures = objLoadResult.Textures.Any(); var initialMediatorIndices = new int?[objLoadResult.Vertices.Count]; var mediators = new List <VertexMediator>(); var faceMediatorIndices = new List <int>(); var indexList = new List <int>(); var materials = new List <IStandardMaterial>(); var modelParts = new List <FlexibleModelPart>(); foreach (var grp in objLoadResult.Groups) { var startIndexLocation = indexList.Count; foreach (var face in grp.Faces) { faceMediatorIndices.Clear(); foreach (var fv in face.EnumerateVertices()) { var newMediator = new VertexMediator { PositionIndex = fv.VertexIndex - 1, NormalIndex = fv.NormalIndex - 1, TexCoordIndex = anyTextures ? fv.TextureIndex - 1 : 0 }; var initialIndex = initialMediatorIndices[newMediator.PositionIndex]; if (!initialIndex.HasValue) { var mediatorIndex = mediators.Count; mediators.Add(newMediator); faceMediatorIndices.Add(mediatorIndex); initialMediatorIndices[newMediator.PositionIndex] = mediatorIndex; } else { var mediatorIndex = initialIndex.Value; var oldMediator = mediators[mediatorIndex]; while (true) { if (oldMediator.PositionIndex == newMediator.PositionIndex && oldMediator.NormalIndex == newMediator.NormalIndex && oldMediator.TexCoordIndex == newMediator.TexCoordIndex) { break; } if (!oldMediator.NextMediator.HasValue) { mediatorIndex = mediators.Count; mediators.Add(newMediator); oldMediator.NextMediator = mediatorIndex; break; } mediatorIndex = oldMediator.NextMediator.Value; oldMediator = mediators[mediatorIndex]; } faceMediatorIndices.Add(mediatorIndex); } } if (faceMediatorIndices.Count <= 3) { for (int i = 0; i < faceMediatorIndices.Count - 3; i++) { indexList.Add(faceMediatorIndices[0]); } foreach (var mi in faceMediatorIndices) { indexList.Add(mi); } } else { for (int i = 0; i < faceMediatorIndices.Count - 2; i++) { indexList.Add(faceMediatorIndices[0]); indexList.Add(faceMediatorIndices[i + 1]); indexList.Add(faceMediatorIndices[i + 2]); } } } var indexCount = indexList.Count - startIndexLocation; var color = grp.Material != null ? new Color4( grp.Material.DiffuseColor.X, grp.Material.DiffuseColor.Y, grp.Material.DiffuseColor.Z) : (Color4?)null; // todo: use material modelParts.Add(new FlexibleModelPart { VertexSetIndex = 0, ModelMaterialName = grp.Material?.Name ?? "DefaultMaterial", PrimitiveTopology = FlexibleModelPrimitiveTopology.TriangleList, IndexCount = indexCount, FirstIndex = startIndexLocation }); } VertexPosNormTex[] finalVertices; int[] finalIndices; if (objLoadResult.Normals.Count > 0) { var vertices = mediators.Select(m => new VertexPosNormTex()).ToArray(); for (int i = 0; i < mediators.Count; i++) { var mediator = mediators[i]; vertices[i].Position = objLoadResult.Vertices[mediator.PositionIndex].ToClarity(); vertices[i].Normal = objLoadResult.Normals[mediator.NormalIndex].ToClarity(); if (anyTextures) { vertices[i].TexCoord = objLoadResult.Textures[mediator.TexCoordIndex].ToClarity(); } } finalVertices = vertices; finalIndices = indexList.ToArray(); } else { var newIndices = Enumerable.Range(0, indexList.Count).ToArray(); var newVertices = new VertexPosNormTex[newIndices.Length]; for (int i = 0; i + 2 < indexList.Count; i += 3) { var mediator0 = mediators[indexList[i]]; var mediator1 = mediators[indexList[i + 1]]; var mediator2 = mediators[indexList[i + 2]]; var pos0 = objLoadResult.Vertices[mediator0.PositionIndex].ToClarity(); var pos1 = objLoadResult.Vertices[mediator1.PositionIndex].ToClarity(); var pos2 = objLoadResult.Vertices[mediator2.PositionIndex].ToClarity(); newVertices[i] = new VertexPosNormTex { Position = pos0, Normal = -Vector3.Cross(pos2 - pos0, pos1 - pos0).Normalize(), TexCoord = new Vector2(0.3f, 0.3f) }; newVertices[i + 1] = new VertexPosNormTex { Position = pos1, Normal = -Vector3.Cross(pos0 - pos1, pos2 - pos1).Normalize(), TexCoord = new Vector2(0.7f, 0.3f) }; newVertices[i + 2] = new VertexPosNormTex { Position = pos2, Normal = -Vector3.Cross(pos1 - pos2, pos0 - pos2).Normalize(), TexCoord = new Vector2(0.5f, 0.7f) }; } finalVertices = newVertices; finalIndices = newIndices; } var pack = new ResourcePack(ResourceVolatility.Immutable); IRawDataResource vertexRawData; fixed(VertexPosNormTex *pVertices = finalVertices) vertexRawData = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pVertices, sizeof(VertexPosNormTex) * finalVertices.Length); pack.AddSubresource("VertexRawData", vertexRawData); IRawDataResource indexRawData; fixed(int *pIndices = finalIndices) indexRawData = new RawDataResource(ResourceVolatility.Immutable, (IntPtr)pIndices, sizeof(int) * finalIndices.Length); pack.AddSubresource("IndexRawData", indexRawData); var arraySubranges = new [] { vertexRawData.GetSubrange(0), indexRawData.GetSubrange(0) }; var elementInfos = VertexPosNormTex.GetElementsInfos(0); var indicesInfo = new VertexIndicesInfo(1, CommonFormat.R32_UINT); var vertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable, arraySubranges, elementInfos, indicesInfo); pack.AddSubresource("VertexSet", vertexSet); var sphere = Sphere.BoundingSphere(finalVertices, x => x.Position); var model = new FlexibleModel(ResourceVolatility.Immutable, new [] { vertexSet }, modelParts, sphere); pack.AddSubresource("Model", model); pack.MainSubresource = model; var hash = AssetHashMd5.FromSingleFile(fileData); var fileName = Path.GetFileName(loadInfo.LoadPath); return(new Asset(loadInfo.AssetName, pack, AssetStorageType.CopyLocal, hash, loadInfo.ReferencePath, fileName)); }
private static AssetLoadResultByLoader Load(AssetLoadInfo loadInfo, void *dicomManager) { int width, height, depth; CheckSuccess(DicomProject.AnalyzerGetDimensions(dicomManager, 1, &width, &height, &depth)); var lowerBuffer = new byte[width * height]; var higherBuffer = new byte[width * height]; var vertexList = new List <VertexPosNormTex>(); fixed(byte *pBuffer = higherBuffer) { int bufferSize = higherBuffer.Length; int bytesWritten; CheckSuccess(DicomProject.AnalyzerGetMonochromePixelDataBufferOfSlice(dicomManager, 1, pBuffer, &bufferSize, &bytesWritten)); } for (int z = 1; z < depth; z++) { CodingHelper.Swap(ref lowerBuffer, ref higherBuffer); fixed(byte *pBuffer = higherBuffer) { int bufferSize = higherBuffer.Length; int bytesWritten; CheckSuccess(DicomProject.AnalyzerGetMonochromePixelDataBufferOfSlice(dicomManager, z + 1, pBuffer, &bufferSize, &bytesWritten)); } for (int y = 0; y < height - 1; y++) { for (int x = 0; x < width - 1; x++) { var vx = (100f / width) * x - 50f; var vy = (100f / height) * y - 50f; var vz = (100f / depth) * z - 50f; var yStride = width; var mcCube = new MCCubeCornerScalarStruct { CubeDim = new IrtPtType(100.0 / width, 100.0 / height, 100.0 / depth), Vrtx0Lctn = new IrtPtType(vx, vy, vz) }; mcCube.Corners[0] = UNormToDouble(lowerBuffer[yStride * y + x]); mcCube.Corners[1] = UNormToDouble(lowerBuffer[yStride * y + (x + 1)]); mcCube.Corners[2] = UNormToDouble(lowerBuffer[yStride * (y + 1) + (x + 1)]); mcCube.Corners[3] = UNormToDouble(lowerBuffer[yStride * (y + 1) + x]); mcCube.Corners[4] = UNormToDouble(higherBuffer[yStride * y + x]); mcCube.Corners[5] = UNormToDouble(higherBuffer[yStride * y + (x + 1)]); mcCube.Corners[6] = UNormToDouble(higherBuffer[yStride * (y + 1) + (x + 1)]); mcCube.Corners[7] = UNormToDouble(higherBuffer[yStride * (y + 1) + x]); // todo: use ref instead EstimateGradient(&mcCube); var MCPolys = Irit.MCThresholdCube(&mcCube, 0.5); while (MCPolys != null) { var texCoord = new Vector2((float)x / width, (float)z / depth); var vertex0 = MCPolys->GetClarityVertex(0, texCoord); var vertexCurr = MCPolys->GetClarityVertex(1, texCoord); for (var i = 2; i < MCPolys->NumOfVertices; i++) { var vertexPrev = vertexCurr; vertexCurr = MCPolys->GetClarityVertex(i, texCoord); vertexList.Add(vertex0); vertexList.Add(vertexPrev); vertexList.Add(vertexCurr); } //Irit.IritFree(MCPolys); MCPolys = MCPolys->Pnext; } } } } var pack = new ResourcePack(ResourceVolatility.Immutable); var rawVerticesData = new RawDataResource(ResourceVolatility.Immutable, vertexList.Count * sizeof(VertexPosNormTex)); pack.AddSubresource("VertexData", rawVerticesData); var pRawData = (VertexPosNormTex *)rawVerticesData.Map(); for (int i = 0; i < vertexList.Count; i++) { pRawData[i] = vertexList[i]; } rawVerticesData.Unmap(true); var vertexSet = new FlexibleModelVertexSet(ResourceVolatility.Immutable, new[] { new RawDataResSubrange(rawVerticesData, 0) }, VertexPosNormTex.GetElementsInfos(0), null); pack.AddSubresource("ModelVertexSet", vertexSet); var modelPart = new FlexibleModelPart { IndexCount = vertexList.Count, PrimitiveTopology = FlexibleModelPrimitiveTopology.TriangleList, VertexSetIndex = 0 }; var model = new FlexibleModel(ResourceVolatility.Immutable, new[] { vertexSet }, new[] { modelPart }, new Sphere(Vector3.Zero, 50)); pack.AddSubresource("Model", model); pack.MainSubresource = model; CheckSuccess(DicomProject.AnalyzerKillDicomAnalyzer(&dicomManager)); // todo: calculate hash honestly var hash = AssetHashMd5.Random(new Random()); var fileName = Path.GetFileName(loadInfo.LoadPath); var asset = new Asset(loadInfo.AssetName, pack, AssetStorageType.ReferenceOriginal, hash, loadInfo.ReferencePath, fileName); return(AssetLoadResultByLoader.Success(asset)); }