void Start() { // Cache the particle system (make sure you have set enough particle count) particles = GetComponent <PlaygroundParticlesC>(); // Create a new skinned world object swo = PlaygroundC.SkinnedWorldObject(skinnedMeshTransform); // Start emission routine StartCoroutine(EmitOverAllVertices()); }
void Start () { // Cache the particle system (make sure you have set enough particle count) particles = GetComponent<PlaygroundParticlesC>(); // Create a new skinned world object swo = PlaygroundC.SkinnedWorldObject(skinnedMeshTransform); // Start emission routine StartCoroutine(EmitOverAllVertices()); }
// Set position from Skinned Mesh World Object public static void SetPosition (ref PlaygroundParticlesC playgroundParticles, ref SkinnedWorldObject particleStateWorldObject) { if (playgroundParticles.skinnedWorldObject==null || playgroundParticles.skinnedWorldObject.mesh==null) { Debug.Log("There is no skinned mesh assigned to "+playgroundParticles.particleSystemGameObject.name+"'s skinnedWorlObject."); return; } Vector3[] vertices = particleStateWorldObject.mesh.vertices; BoneWeight[] weights = particleStateWorldObject.mesh.boneWeights; Matrix4x4[] bindposes = particleStateWorldObject.mesh.bindposes; Matrix4x4[] boneMatrices = new Matrix4x4[particleStateWorldObject.renderer.bones.Length]; int i = 0; for (; i<boneMatrices.Length; i++) boneMatrices[i] = particleStateWorldObject.renderer.bones[i].localToWorldMatrix * bindposes[i]; Matrix4x4 vertexMatrix = new Matrix4x4(); for (i = 0; i<playgroundParticles.particleCache.particles.Length; i++) { BoneWeight weight = weights[i]; Matrix4x4 m0 = boneMatrices[weight.boneIndex0]; Matrix4x4 m1 = boneMatrices[weight.boneIndex1]; Matrix4x4 m2 = boneMatrices[weight.boneIndex2]; Matrix4x4 m3 = boneMatrices[weight.boneIndex3]; for(int n=0;n<16;n++){ vertexMatrix[n] = m0[n] * weight.weight0 + m1[n] * weight.weight1 + m2[n] * weight.weight2 + m3[n] * weight.weight3; } playgroundParticles.particleCache.particles[i].position = vertexMatrix.MultiplyPoint3x4(vertices[i%vertices.Length])+GetOverflowOffset(ref playgroundParticles, i, vertices.Length); } }
// Get vertices from a skinned world object in a Vector3-array public static void GetPosition (ref Vector3[] v3, ref Vector3[] norm, ref SkinnedWorldObject particleStateWorldObject) { Vector3[] vertices = particleStateWorldObject.mesh.vertices; norm = particleStateWorldObject.mesh.normals; BoneWeight[] weights = particleStateWorldObject.mesh.boneWeights; Matrix4x4[] bindPoses = particleStateWorldObject.mesh.bindposes; Matrix4x4[] boneMatrices = new Matrix4x4[particleStateWorldObject.renderer.bones.Length]; if (v3.Length!=vertices.Length) v3 = new Vector3[vertices.Length]; int i = 0; for (; i<boneMatrices.Length; i++) boneMatrices[i] = particleStateWorldObject.renderer.bones[i].localToWorldMatrix * bindPoses[i]; Matrix4x4 vertexMatrix = new Matrix4x4(); for (i = 0; i<v3.Length; i++) { BoneWeight weight = weights[i]; Matrix4x4 m0 = boneMatrices[weight.boneIndex0]; Matrix4x4 m1 = boneMatrices[weight.boneIndex1]; Matrix4x4 m2 = boneMatrices[weight.boneIndex2]; Matrix4x4 m3 = boneMatrices[weight.boneIndex3]; for(int n=0;n<16;n++){ vertexMatrix[n] = m0[n] * weight.weight0 + m1[n] * weight.weight1 + m2[n] * weight.weight2 + m3[n] * weight.weight3; } v3[i] = vertexMatrix.MultiplyPoint3x4(vertices[(i)%vertices.Length]); } }
// Lerp to a Skinned World Object public static void Lerp (PlaygroundParticlesC playgroundParticles, SkinnedWorldObject particleStateWorldObject, float time) { if(time<0) time = 0f; Vector3[] vertices = particleStateWorldObject.mesh.vertices; BoneWeight[] weights = particleStateWorldObject.mesh.boneWeights; Matrix4x4[] boneMatrices = new Matrix4x4[particleStateWorldObject.renderer.bones.Length]; int i; for (i = 0; i<boneMatrices.Length; i++) boneMatrices[i] = particleStateWorldObject.renderer.bones[i].localToWorldMatrix * particleStateWorldObject.mesh.bindposes[i]; Matrix4x4 vertexMatrix = new Matrix4x4(); for (i = 0; i<playgroundParticles.particleCache.particles.Length; i++) { BoneWeight weight = weights[i]; Matrix4x4 m0 = boneMatrices[weight.boneIndex0]; Matrix4x4 m1 = boneMatrices[weight.boneIndex1]; Matrix4x4 m2 = boneMatrices[weight.boneIndex2]; Matrix4x4 m3 = boneMatrices[weight.boneIndex3]; for(int n=0;n<16;n++){ vertexMatrix[n] = m0[n] * weight.weight0 + m1[n] * weight.weight1 + m2[n] * weight.weight2 + m3[n] * weight.weight3; } playgroundParticles.particleCache.particles[i].position = Vector3.Lerp(playgroundParticles.particleCache.particles[i].position, vertexMatrix.MultiplyPoint3x4(vertices[i%vertices.Length]), time); } }
// Create a new SkinnedWorldObject public static SkinnedWorldObject NewSkinnedWorldObject (PlaygroundParticlesC playgroundParticles, Transform meshTransform) { SkinnedWorldObject worldObject = new SkinnedWorldObject(); if (meshTransform.GetComponentInChildren<SkinnedMeshRenderer>()) { worldObject.transform = meshTransform; worldObject.gameObject = meshTransform.gameObject; worldObject.rigidbody = meshTransform.rigidbody; worldObject.renderer = meshTransform.GetComponentInChildren<SkinnedMeshRenderer>(); worldObject.mesh = worldObject.renderer.sharedMesh; worldObject.vertexPositions = new Vector3[worldObject.mesh.vertexCount]; worldObject.normals = worldObject.mesh.normals; worldObject.cachedId = worldObject.gameObject.GetInstanceID(); playgroundParticles.skinnedWorldObject = worldObject; } else Debug.Log("Could not find a skinned mesh in "+meshTransform.name+"."); return worldObject; }
// Get vertices and normals from a skinned world object in Vector3[] format (notice that the array is modified by reference) public static void GetPosition (ref Vector3[] vertices, ref Vector3[] normals, ref SkinnedWorldObject particleStateWorldObject) { PlaygroundParticlesC.GetPosition(ref vertices,ref normals,ref particleStateWorldObject); }
// Set new mesh position from mesh world object state instantly public static void SetPosition (ref PlaygroundParticlesC playgroundParticles, ref SkinnedWorldObject particleStateWorldObject) { PlaygroundParticlesC.SetPosition(ref playgroundParticles,ref particleStateWorldObject); }
// Linear interpolation to object in world space public static void Lerp (PlaygroundParticlesC playgroundParticles, SkinnedWorldObject particleStateWorldObject, float time) { PlaygroundParticlesC.Lerp(playgroundParticles,particleStateWorldObject,time); }