public void Populate(TiltBrush.GeometryPool pool) { positionAccessor.Populate(pool.m_Vertices, flipY: false, calculateMinMax: true); if (normalAccessor != null) { normalAccessor.Populate(pool.m_Normals, flipY: false, calculateMinMax: false); } if (colorAccessor != null) { colorAccessor.Populate(pool.m_Colors); } if (tangentAccessor != null) { tangentAccessor.Populate(pool.m_Tangents, flipY: false, calculateMinMax: false); } // UVs may be 1, 2, 3 or 4 element tuples, which the following helper method resolves. // In the case of zero UVs, the texCoord accessor will be null and will not be populated. Debug.Assert(TiltBrush.GeometryPool.kNumTexcoords == 3); Debug.Assert(texCoord3Accessor == null); var layout = pool.Layout; PopulateUv(0, pool, texCoord0Accessor, layout.texcoord0.semantic); PopulateUv(1, pool, texCoord1Accessor, layout.texcoord1.semantic); PopulateUv(2, pool, texCoord2Accessor, layout.texcoord2.semantic); PopulateUv(3, pool, texCoord3Accessor, Semantic.Unspecified); }
public void Populate(TiltBrush.GeometryPool pool) { pool.EnsureGeometryResident(); if (primitives.Count > 0) { // Vertex data is shared among all the primitives in the mesh, so only do [0] primitives[0].attributes.Populate(pool); primitives[0].Populate(pool); // I guess someone might want to map Unity submeshes -> gltf primitives. // - First you'd want to make sure that consuming tools won't freak out about that, // since it doesn't seem to be the intended use for the mesh/primitive distinction. // See https://github.com/KhronosGroup/glTF/issues/1278 // - Then you'd want Populate() to take multiple GeometryPools, one per MeshSubset. // - Then you'd want those GeometryPools to indicate somehow whether their underlying // vertex data is or can be shared -- maybe do this in GeometryPool.FromMesh() // by having them point to the same Lists. // - Then you'd want to make GlTF_attributes.Populate() smart enough to understand that // sharing (ie, memoizing on the List<Vector3> pointer) // None of that is implemented, which is okay since our current gltf generation // code doesn't add more than one GlTF_Primitive per GlTF_Mesh. if (primitives.Count > 1) { Debug.LogError("More than one primitive per mesh is unimplemented and unsupported"); } } // The mesh data is only ever needed once (because it only goes into the .bin // file once), but ExportMeshGeomPool still uses bits of data like pool.NumTris // so we can't destroy it. // // We could MakeNotResident(filename) again, but that's wasteful and I'd need to // add an API to get the cache filename. So this "no coming back" API seems like // the most expedient solution. // TODO: replace this hack with something better? eg, a way to reload from // file without destroying the file? // pool.Destroy(); pool.MakeGeometryPermanentlyNotResident(); }
public void Populate(TiltBrush.GeometryPool pool) { indices.PopulateUshort(pool.m_Tris.ToArray()); }
private void PopulateUv( int channel, TiltBrush.GeometryPool pool, GlTF_Accessor accessor, Semantic semantic) { bool packVertId = m_layout.PackVertexIdIntoTexcoord1W && channel == 1; if (packVertId) { // Guaranteed by GlTF_VertexLayout Debug.Assert(m_layout.m_tbLayout.GetTexcoordInfo(channel).size == 3); Debug.Assert(m_layout.GetTexcoordSize(channel) == 4); } if (accessor == null) { return; } if (channel < 0 || channel > 3) { throw new ArgumentException("Invalid channel"); } TiltBrush.GeometryPool.TexcoordData texcoordData = pool.GetTexcoordData(channel); if (semantic == Semantic.XyIsUvZIsDistance && accessor.type != GlTF_Accessor.Type.VEC3) { throw new ArgumentException("XyIsUvZIsDistance semantic can only be applied to VEC3"); } bool flipY; if (semantic == Semantic.Unspecified && channel == 0 && accessor.type == GlTF_Accessor.Type.VEC2) { Debug.LogWarning("Assuming Semantic.XyIsUv"); semantic = Semantic.XyIsUv; } switch (semantic) { case Semantic.Position: case Semantic.Vector: case Semantic.Timestamp: flipY = false; break; case Semantic.XyIsUvZIsDistance: case Semantic.XyIsUv: flipY = true; break; default: throw new ArgumentException("semantic"); } switch (accessor.type) { case GlTF_Accessor.Type.SCALAR: throw new NotImplementedException(); case GlTF_Accessor.Type.VEC2: accessor.Populate(texcoordData.v2, flipY: flipY, calculateMinMax: false); break; case GlTF_Accessor.Type.VEC3: accessor.Populate(texcoordData.v3, flipY: flipY, calculateMinMax: false); break; case GlTF_Accessor.Type.VEC4: if (packVertId) { // In the vertexId case, we actually have a vec3, which needs to be augmented to a vec4. // TODO: this should happen at some higher level. int i = 0; var v4 = texcoordData.v3.ConvertAll <Vector4>((v => new Vector4(v.x, v.y, v.z, i++))); accessor.Populate(v4, flipY: flipY, calculateMinMax: false); } else { accessor.Populate(texcoordData.v4, flipY: flipY, calculateMinMax: false); } break; default: throw new ArgumentException("Unexpected accessor.type"); } }