Beispiel #1
0
        // 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);
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }