private DefaultVertex[] CreateDefaultVertexArray() { var geometry = (MeshGeometry3D)this.Geometry; var colors = geometry.Colors != null?geometry.Colors.ToArray() : null; var textureCoordinates = geometry.TextureCoordinates != null?geometry.TextureCoordinates.ToArray() : null; var texScale = this.TextureCoodScale; var normals = geometry.Normals != null?geometry.Normals.ToArray() : null; var tangents = geometry.Tangents != null?geometry.Tangents.ToArray() : null; var bitangents = geometry.BiTangents != null?geometry.BiTangents.ToArray() : null; var positions = geometry.Positions.ToArray(); var vertexCount = geometry.Positions.Count; var result = new DefaultVertex[vertexCount]; for (var i = 0; i < vertexCount; i++) { result[i] = new DefaultVertex { Position = new Vector4(positions[i], 1f), Color = colors != null ? colors[i] : Color4.White, TexCoord = textureCoordinates != null ? texScale * textureCoordinates[i] : Vector2.Zero, Normal = normals != null ? normals[i] : Vector3.Zero, Tangent = tangents != null ? tangents[i] : Vector3.Zero, BiTangent = bitangents != null ? bitangents[i] : Vector3.Zero, }; } return(result); }
public void LoadMesh() { if (this.skinnedMeshRenderer == null) { this.skinnedMeshRenderer = this.GetComponentInChildren <SkinnedMeshRenderer>(); } // Clone mesh and save it to SkinnedMeshRenderer if (!skinnedMeshRenderer.sharedMesh.name.Contains("Clone")) { this._mesh = this.skinnedMeshRenderer.sharedMesh; this._mesh = GameObject.Instantiate(this._mesh); this._mesh.MarkDynamic(); this.skinnedMeshRenderer.sharedMesh = this._mesh; } else { this._mesh = this.skinnedMeshRenderer.sharedMesh; } // Save Vertices positions var vertices = this._mesh.vertices; int length = vertices.Length; this._defaultMeshVertices = new DefaultVertex[length]; for (int i = 0; i < length; i++) { _defaultMeshVertices[i] = new DefaultVertex(i, vertices[i]); } }
/// <summary> /// Convert from Unity vectors to convex hull vectors /// </summary> /// <param name="p"></param> /// <returns></returns> static DefaultVertex VertOfVector3(Vector3 p) { double[] d = new double[3]; d[0] = p.x; d[1] = p.y; d[2] = p.z; DefaultVertex vert = new DefaultVertex(); vert.Position = d; return(vert); }
public static void CompileDefaults() { if (DefaultVertex != null && DefaultVertex.IsValid) { DefaultVertex.Dispose(); } DefaultVertex = new Shader(Shader.ShaderType.Vertex, "DefaultVertex", @" #version 140 uniform mat4 projectionMatrix; uniform vec3 instancePosition[<instances>]; uniform vec3 instanceScale[<instances>]; uniform vec2 instanceUVXY[<instances>]; uniform vec2 instanceUVWH[<instances>]; in vec3 vPosition; in vec2 vUV; in vec4 vColor; out vec4 fColor; out vec2 UV; void main() { gl_Position = projectionMatrix * vec4(vPosition * instanceScale[gl_InstanceID] + instancePosition[gl_InstanceID], 1.0); fColor = vColor; UV = instanceUVXY[gl_InstanceID] + instanceUVWH[gl_InstanceID] * vUV; }"); if (DefaultFragment != null && DefaultFragment.IsValid) { DefaultFragment.Dispose(); } DefaultFragment = new Shader(Shader.ShaderType.Fragment, "DefaultFragment", @" #version 140 uniform sampler2D textureSampler; in vec4 fColor; in vec2 UV; out vec4 fragColor; void main() { fragColor = fColor * texture( textureSampler, UV ); }"); }
static DefaultVertex[] CreateRandomVertices(int dim, int numVert, double size) { var vertices = new DefaultVertex[numVert]; for (var i = 0; i < numVert; i++) { double[] v = new double[dim]; for (int j = 0; j < dim; j++) { v[j] = size * rnd.NextDouble(); } vertices[i] = new DefaultVertex { Position = v }; } return(vertices); }
static DefaultVertex[] CreateRandomVertices(int dim, int numVert, double size) { var vertices = new DefaultVertex[numVert]; for (var i = 0; i < numVert; i++) { double[] v = new double[dim]; for (int j = 0; j < dim; j++) { v[j] = size * rnd.NextDouble(); } vertices[i] = new DefaultVertex { Position = v }; } ////File.WriteAllLines("i:/test/7Ddata.txt", //// new string[] { "7 test", numVert.ToString() } //// .Concat(vertices.Select(v => string.Join(" ", v.Position.Select(p => p.ToString())))) //// .ToArray() //// ); return(vertices); }
// Use this for initialization void Start() { if (this.skinnedMeshRenderer == null) { this.skinnedMeshRenderer = this.GetComponentInChildren <SkinnedMeshRenderer>(); } // オリジナルのメッシュが入っているときはCloneを作成する if (!skinnedMeshRenderer.sharedMesh.name.Contains("Clone")) { this._mesh = this.skinnedMeshRenderer.sharedMesh; this._mesh = GameObject.Instantiate(this._mesh); this._mesh.MarkDynamic(); this.skinnedMeshRenderer.sharedMesh = this._mesh; } else { this._mesh = this.skinnedMeshRenderer.sharedMesh; } var vertices = _mesh.vertices; int length = index.Length; _defaultMeshVertices = new DefaultVertex[length]; for (int i = 0; i < length; i++) { _defaultMeshVertices[i] = new DefaultVertex(); _defaultMeshVertices[i].Index = index[i]; _defaultMeshVertices[i].Vertex = vertices[index[i]]; } //skinnedMeshRenderer.sharedMesh.vertices = vertices; //skinnedMeshRenderer.sharedMesh.RecalculateNormals(); //skinnedMeshRenderer.sharedMesh.RecalculateBounds(); }
private void GetVertexDataUnscaled(out List <DefaultVertex> outVertices, out List <uint> outIndices) { var modelData = AssetLoader.LoadModel(Path.Combine(AssetLocator.ModelsDir, ModelFileName)); outIndices = modelData.GetIndices().ToList(); outVertices = modelData.GetVertices <DefaultVertex>(typeof(DefaultVertex).GetConstructor(new[] { typeof(Vector3), typeof(Vector3), typeof(Vector3), typeof(Vector2) })).ToList(); if (MirrorX) { for (int i = 0; i < outVertices.Count; i++) { Vector3 originalPos = outVertices[i].Position; outVertices[i] = new DefaultVertex( new Vector3(originalPos, x: -originalPos.X), new Vector3(outVertices[i].Normal, x: -outVertices[i].Normal.X), outVertices[i].TexUV ); } for (int i = 0; i < outIndices.Count; i += 3) { uint index1 = outIndices[i]; outIndices[i] = outIndices[i + 1]; outIndices[i + 1] = index1; } } else { for (int i = 0; i < outVertices.Count; i++) { outVertices[i] = new DefaultVertex( outVertices[i].Position, outVertices[i].Normal, outVertices[i].TexUV ); } } }
// Helper method for marshaling mesh data with sub mesh definition public static void BuildSceneContext(MeshFilter[] meshes, List <List <int> > subMeshIndices, List <List <int> > subMeshTriangleIndices, BakeContext ctx, IVertex vertex = null) { if (vertex == null) { vertex = new DefaultVertex(); } ctx.m_vertexEementCount = vertex.ElementCount; ctx.m_vertexDefinition = vertex.Definition.ToArray(); int totalVertCount = 0; int totalTriCount = 0; int meshCount = meshes.Length; // extract mesh renderer options MeshRenderer[] renderer = ctx.m_meshRenderers; // calculate mesh data size for (int i = 0; i < meshCount; ++i) { // if a sub mesh is defined use it for vert count if (subMeshIndices != null && subMeshIndices[i] != null) { totalVertCount += subMeshIndices[i].Count; } else { totalVertCount += meshes[i].sharedMesh.vertices.Length; } // if a sub mesh is defined use it for triangle index count if (subMeshTriangleIndices != null && subMeshTriangleIndices[i] != null) { totalTriCount += subMeshTriangleIndices[i].Count; } else { totalTriCount += meshes[i].sharedMesh.triangles.Length; } } // data size const int triangleSize = 3; const int matSize = 16; int totalMatrixDataSize = matSize * meshCount * SIZE_FLOAT; // mesh size depends on vertex definition int totalMeshDataSize = totalVertCount * SIZE_FLOAT * (vertex.VertexSize + meshCount); int totalTriangleDataSize = totalTriCount * triangleSize * SIZE_INT; VertexBakerLib instance = VertexBakerLib.Instance; ctx.m_meshIdsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_vertexCountsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_triangleCountPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_matDataPtr = instance.Alloc(totalMatrixDataSize); ctx.m_meshDataPtr = instance.Alloc(totalMeshDataSize); ctx.m_triangleDataPtr = instance.Alloc(totalTriangleDataSize); ctx.m_settingsIndicesPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_bakeOptionsPtr = instance.Alloc(meshCount * SIZE_INT); ctx.m_layerPtr = instance.Alloc(meshCount * SIZE_INT); // temp buffer for matrix float[] matArr = new float[16]; int matDestOffset = 0; int meshDestOffset = 0; int triangleDestOffset = 0; int[] vertexCounts = new int[meshCount]; int[] triangleCounts = new int[meshCount]; int[] ids = new int[meshCount]; uint[] perMeshBakeOpt = new uint[meshCount]; uint[] layerMask = new uint[meshCount]; // data for settings int[] settingsIdx = new int[meshCount]; List <IntPtr> settingsList = new List <IntPtr>(); // global settings int globalSettingsIdx = 0; IntPtr globalSettings = SettingsToIntPtr(BakeData.Instance().GetBakeSettings().SelectedBakeSet); settingsList.Add(globalSettings); for (int m = 0; m < meshCount; ++m) { bool processSubMesh = false; // assume sub mesh if (subMeshIndices != null && subMeshIndices[m] != null && subMeshTriangleIndices != null && subMeshTriangleIndices[m] != null) { processSubMesh = true; } // setup settings settingsIdx[m] = globalSettingsIdx; // check for override settings VertexLightingOverride ovrdSettings = meshes[m].GetComponent <VertexLightingOverride>(); if (ovrdSettings != null) { // point at this overrides index settingsIdx[m] = settingsList.Count; // ensure ambient settings (copy from global which contains the valid ambient settings for now) ovrdSettings.m_bakeSettingsOverride.CopyAmbient(BakeData.Instance().GetBakeSettings().SelectedBakeSet); IntPtr settingsPtr = SettingsToIntPtr(ovrdSettings.m_bakeSettingsOverride); settingsList.Add(settingsPtr); } Mesh mesh = meshes[m].sharedMesh; ids[m] = meshes[m].GetUniqueId(); // layer mask layerMask[m] = (uint)(1 << meshes[m].gameObject.layer); // clear data perMeshBakeOpt[m] = 0; // if mesh has no normals or tangents flag them for generation // should calculate normals if (meshes[m].sharedMesh.normals.Length == 0) { // set bit for normals perMeshBakeOpt[m] |= BakeOptions.kCalcNormals; } // should calculate tangents if (meshes[m].sharedMesh.tangents.Length == 0) { // set bit for tangents perMeshBakeOpt[m] |= BakeOptions.kCalcTangents; } // extract shadowing options from renderer switch (renderer[m].shadowCastingMode) { case UnityEngine.Rendering.ShadowCastingMode.Off: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOff; } break; case UnityEngine.Rendering.ShadowCastingMode.TwoSided: { perMeshBakeOpt[m] |= BakeOptions.kTwoSided; } break; case UnityEngine.Rendering.ShadowCastingMode.On: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOn; } break; case UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly: { perMeshBakeOpt[m] |= BakeOptions.kShadowsOnly; } break; default: break; } if (renderer[m].receiveShadows) { perMeshBakeOpt[m] |= BakeOptions.kReceiveShadow; } else { perMeshBakeOpt[m] &= ~BakeOptions.kReceiveShadow; } // use the list of unique indices of the sub mesh to find the count here unless its null then assume all vertices are being processed int vertexCount = processSubMesh ? subMeshIndices[m].Count : mesh.vertices.Length; // use the list of triangles from the sub mesh to find the count here unless its null then assume all triangles are being processed int triangleCount = processSubMesh ? subMeshTriangleIndices[m].Count : mesh.triangles.Length; vertexCounts[m] = vertexCount; triangleCounts[m] = triangleCount; // copy mesh data into mesh buffer starting with world matrix int matIndex = 0; AssignMat4(ref matArr, meshes[m].transform.localToWorldMatrix, ref matIndex); // 64 bytes IntPtr matDestPtr = new IntPtr(ctx.m_matDataPtr.ToInt64() + matDestOffset * SIZE_FLOAT); Marshal.Copy(matArr, 0, matDestPtr, 16); matDestOffset += 16; if (processSubMesh) { // build sub mesh BuildMesh(ctx, meshes[m].sharedMesh, vertex, subMeshIndices[m], ref meshDestOffset); } else { // build entire mesh BuildMesh(ctx, meshes[m].sharedMesh, vertex, ref meshDestOffset); } // triangles IntPtr indexPtr = new IntPtr(ctx.m_triangleDataPtr.ToInt64() + triangleDestOffset * SIZE_INT); if (processSubMesh) { // copy sub mesh triangle list Marshal.Copy(subMeshTriangleIndices[m].ToArray(), 0, indexPtr, triangleCount); } else { // copy entire triangle list Marshal.Copy(mesh.triangles, 0, indexPtr, triangleCount); } triangleDestOffset += triangleCount; } // copy the mesh into pointer instance.CopyArray(ctx.m_meshIdsPtr, meshCount * SIZE_INT, ids, meshCount * SIZE_INT); instance.CopyArray(ctx.m_vertexCountsPtr, meshCount * SIZE_INT, vertexCounts, meshCount * SIZE_INT); instance.CopyArray(ctx.m_triangleCountPtr, meshCount * SIZE_INT, triangleCounts, meshCount * SIZE_INT); instance.CopyUIntArray(ctx.m_bakeOptionsPtr, meshCount * SIZE_INT, perMeshBakeOpt, meshCount * SIZE_INT); instance.CopyUIntArray(ctx.m_layerPtr, meshCount * SIZE_INT, layerMask, meshCount * SIZE_INT); instance.CopyArray(ctx.m_settingsIndicesPtr, meshCount * SIZE_INT, settingsIdx, meshCount * SIZE_INT); ctx.m_settingsPtrs = settingsList.ToArray(); ctx.m_vertCounts = vertexCounts; }
/// <summary> /// Convert from convex hull vectors to Unity vectors /// </summary> /// <param name="v"></param> /// <returns></returns> static Vector3 Vector3OfVert(DefaultVertex v) { return(new Vector3((float)v.Position[0], (float)v.Position[1], (float)v.Position[2])); }
public static LevelDescription Load(string fullFilePath, bool includePTD = true) { if (!IOUtils.IsValidFilePath(fullFilePath)) { throw new ArgumentException("File path is not valid.", "fullFilePath"); } XDocument loadFile = XDocument.Load(fullFilePath); XElement metaElement = loadFile.Root.Element(FILE_ELEMENT_NAME_META); XElement geometryElement = loadFile.Root.Element(FILE_ELEMENT_NAME_GEOMETRY); XElement materialsElement = loadFile.Root.Element(FILE_ELEMENT_NAME_MATERIALS); XElement entitiesElement = loadFile.Root.Element(FILE_ELEMENT_NAME_GEOM_ENTITIES); LevelDescription loadedLevel; string fileType = metaElement.Element(FILE_ELEMENT_NAME_META_TYPE).Value; string title = metaElement.Element(FILE_ELEMENT_NAME_META_TITLE).Value; if (fileType == FILE_ELEMENT_VALUE_META_TYPE_SKY) { loadedLevel = new SkyLevelDescription(title); } else { loadedLevel = new GameLevelDescription(title); } lock (loadedLevel.instanceMutationLock) { loadedLevel.DeserializeMeta(metaElement); loadedLevel.DeserializeGeometry(geometryElement); loadedLevel.DeserializeMaterials(materialsElement); loadedLevel.DeserializeGeomEntities(entitiesElement); loadedLevel.ChildDeserialize(loadFile); var fullPTDFilePath = Path.Combine(AssetLocator.LevelsDir, Path.GetFileNameWithoutExtension(fullFilePath)) + ".ptd"; if (!File.Exists(fullPTDFilePath)) { if (!EntryPoint.InEditor && loadedLevel is GameLevelDescription) { Logger.Warn("No pretriangulation data found for level '" + fullFilePath + "' -> '" + fullPTDFilePath + "'. Loading time will be longer."); } } else if (includePTD) { GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(2, GCCollectionMode.Forced, true); using (FileStream fileStream = File.Open(fullPTDFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader br = new BinaryReader(fileStream); int geomCount = br.ReadInt32(); for (int g = 0; g < geomCount; ++g) { int geomID = br.ReadInt32(); int numVertices = br.ReadInt32(); int numIndices = br.ReadInt32(); List <DefaultVertex> vertexList = new List <DefaultVertex>(numVertices); List <uint> indexList = new List <uint>(numIndices); for (int i = 0; i < numVertices; ++i) { DefaultVertex vert = new DefaultVertex( position: new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), normal: new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), texUv: new Vector2(br.ReadSingle(), br.ReadSingle()), tangent: new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()) ); vertexList.Add(vert); } for (int i = 0; i < numIndices; ++i) { indexList.Add(br.ReadUInt32()); } loadedLevel.precalculatedTriangles.Add(geomID, Tuple.Create(vertexList, indexList)); } } GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(2, GCCollectionMode.Forced, true); } } return(loadedLevel); }