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);
	}