protected override void OnUpdate() { var charBuffers = GetBufferFromEntity <CharElement>(true); Entities.With(unmappedMeshQuery).ForEach( (Entity e, DynamicBuffer <MeshVertexData> b0, DynamicBuffer <TriangleIndexElement> b1) => { var vertices = b0.AsNativeArray(); var indices = b1.AsNativeArray(); var pair = TryGetFreeMesh(); var mesh = pair.Mesh; mesh.SetVertexBufferParams(vertices.Length, MeshVertexDataExtensions.VertexDescriptors); mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length, 0); mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt16); mesh.SetIndexBufferData(indices, 0, 0, indices.Length); mesh.subMeshCount = 1; mesh.SetSubMesh(0, new SubMeshDescriptor(0, indices.Length, MeshTopology.Triangles)); mesh.RecalculateBounds(); mesh.UploadMeshData(false); cached.Add(pair); var meshIdx = cached.IndexOf(pair); var meshKey = new MeshIndex { Value = meshIdx }; PostUpdateCommands.AddComponent(e, meshKey); }); }
public static void UpdateCacheForEmitMesh(Mesh mesh, int uvChannel) { var meshIndex = new MeshIndex(mesh, uvChannel); if (s_meshStore.ContainsKey(meshIndex)) { GenerateMeshData(meshIndex); } }
public static ComputeBuffer GetMeshBuffer(Mesh mesh, int uvChannel) { var meshIndex = new MeshIndex(mesh, uvChannel); if (!s_meshStore.TryGetValue(meshIndex, out ComputeBuffer buffer)) { buffer = GenerateMeshData(meshIndex); } return(buffer); }
public static void ReleaseCacheForEmitMesh(Mesh mesh, int uvChannel) { var meshIndex = new MeshIndex(mesh, uvChannel); if (s_meshStore.ContainsKey(meshIndex)) { var buffer = s_meshStore[meshIndex]; buffer.Dispose(); s_meshStore.Remove(meshIndex); } }
public override int GetHashCode() { unchecked { var hash = 13; hash = (7 * hash) + MeshIndex.GetHashCode(); hash = (7 * hash) + CameraSlotIndex.GetHashCode(); hash = (7 * hash) + TextureSlotIndex.GetHashCode(); hash = (7 * hash) + MaterialSlotIndex.GetHashCode(); hash = (7 * hash) + VariantKey.GetHashCode(); return(hash); } }
internal static Renderer AddMeshIndicator(GameObject mainObj, WispSkinnedEffect skin, MaterialType matType, MeshIndex mesh, Boolean useParticle = false, Boolean particleScaleToSize = false, Single timeToFullsize = 1f, Single duration = 10f, Boolean scaleX = true, Boolean scaleY = true, Boolean scaleZ = true) { if (!meshIndCounter.ContainsKey(mainObj)) { meshIndCounter[mainObj] = 0u; } var obj = new GameObject("MeshIndicator" + meshIndCounter[mainObj]++); obj.transform.parent = mainObj.transform; obj.transform.localPosition = Vector3.zero; obj.transform.localScale = Vector3.one; obj.transform.localRotation = Quaternion.identity; Renderer renderer = null; Mesh m = AssetsCore.LoadAsset <Mesh>(mesh); if (useParticle) { var ps = obj.AddComponent <ParticleSystem>(); var psr = obj.AddOrGetComponent <ParticleSystemRenderer>(); renderer = psr; psr.renderMode = ParticleSystemRenderMode.Mesh; psr.alignment = ParticleSystemRenderSpace.World; psr.mesh = m; BasicSetup(ps); ps.useAutoRandomSeed = true; var psMain = ps.main; psMain.duration = duration; psMain.loop = false; psMain.startDelay = 0f; psMain.startLifetime = duration; psMain.startSpeed = 0f; psMain.startSize3D = false; psMain.startSize = 1f; psMain.startRotation3D = false; psMain.startRotation = 0f; psMain.flipRotation = 0f; psMain.startColor = Color.white; psMain.gravityModifier = 0f; psMain.simulationSpace = ParticleSystemSimulationSpace.Local; psMain.useUnscaledTime = false; psMain.scalingMode = ParticleSystemScalingMode.Hierarchy; psMain.playOnAwake = true; psMain.emitterVelocityMode = ParticleSystemEmitterVelocityMode.Transform; psMain.maxParticles = 1; psMain.stopAction = ParticleSystemStopAction.None; psMain.cullingMode = ParticleSystemCullingMode.PauseAndCatchup; psMain.ringBufferMode = ParticleSystemRingBufferMode.Disabled; var psEmis = ps.emission; psEmis.enabled = true; psEmis.burstCount = 1; psEmis.SetBurst(0, new ParticleSystem.Burst(0f, 1)); psEmis.rateOverTime = 0f; psEmis.rateOverDistance = 0f; if (particleScaleToSize) { var frac = timeToFullsize / duration; var psSOL = ps.sizeOverLifetime; psSOL.enabled = true; if (scaleX == false && scaleY == false && scaleZ == false) { psSOL.separateAxes = false; psSOL.size = new ParticleSystem.MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0f, frac, 1f)); } else { psSOL.separateAxes = true; psSOL.x = scaleX ? new ParticleSystem.MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0f, frac, 1f)) : 1f; psSOL.y = scaleX ? new ParticleSystem.MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0f, frac, 1f)) : 1f; psSOL.z = scaleX ? new ParticleSystem.MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0f, frac, 1f)) : 1f; } } } else { var meshRend = obj.AddComponent <MeshRenderer>(); var meshFilter = obj.AddOrGetComponent <MeshFilter>(); renderer = meshRend; meshFilter.sharedMesh = m; } if (matType != MaterialType.Constant) { skin.AddRenderer(renderer, matType); } return(renderer); }
static ComputeBuffer GenerateMeshData(MeshIndex meshIndex) { var mesh = meshIndex.Mesh; var uvChannel = meshIndex.UvChannel; //Build mesh data structure mesh.GetVertices(s_verts); mesh.GetNormals(s_normals); mesh.GetTriangles(s_triangles, 0); int count = s_triangles.Count / 3; uvChannel = Mathf.Clamp(uvChannel, 0, 4); mesh.GetUVs(uvChannel, s_uvs); //TODO: Reuse face somehow? ComputeBuffer buffer; if (!s_meshStore.TryGetValue(meshIndex, out buffer)) { buffer = new ComputeBuffer(count, ParticleComponent.SizeOf <Face>()); s_meshStore[meshIndex] = buffer; } else { if (buffer == null || buffer.count != count) { if (buffer != null) { buffer.Dispose(); } buffer = new ComputeBuffer(count, ParticleComponent.SizeOf <Face>()); s_meshStore[meshIndex] = buffer; } } while (s_faces.Length < buffer.count) { Array.Resize(ref s_faces, s_faces.Length * 2); } float totalArea = 0.0f; //TODO: Can't we parralise this easily? for (int i = 0; i < count; ++i) { int i3 = i * 3; int t0 = s_triangles[i3 + 0]; int t1 = s_triangles[i3 + 1]; int t2 = s_triangles[i3 + 2]; s_faces[i] = new Face { a = s_verts[t0], b = s_verts[t1], c = s_verts[t2], na = s_normals[t0], nb = s_normals[t1], nc = s_normals[t2], uva = s_uvs[t0], uvb = s_uvs[t1], uvc = s_uvs[t2] }; //Calculate area of triangle manually. //Equivalent to 0.5 * | (a - b) x (a - c) | float x1 = s_verts[t0].x - s_verts[t1].x; float x2 = s_verts[t0].y - s_verts[t1].y; float x3 = s_verts[t0].z - s_verts[t1].z; float y1 = s_verts[t0].x - s_verts[t2].x; float y2 = s_verts[t0].y - s_verts[t2].y; float y3 = s_verts[t0].z - s_verts[t2].z; float r1 = x2 * y3 - x3 * y2; float r2 = x3 * y1 - x1 * y3; float r3 = x1 * y2 - x2 * y1; float area = 0.5f * Mathf.Sqrt(r1 * r1 + r2 * r2 + r3 * r3); s_faces[i].cweight = area; totalArea += area; } float cumulative = 0; for (int i = 0; i < count; ++i) { cumulative += s_faces[i].cweight / totalArea; s_faces[i].cweight = cumulative; } buffer.SetData(s_faces, 0, 0, count); return(buffer); }