public SimplexNoise turbulenceSimplex; // The Simplex Noise of this manipulator property /// <summary> /// Updates this ManipulatorPropertyC. /// </summary> public void Update () { if (type==MANIPULATORPROPERTYTYPEC.Target) { for (int i = 0; i<targets.Count; i++) targets[i].Update(); } else if (type==MANIPULATORPROPERTYTYPEC.MeshTarget) { if (meshTarget.gameObject!=null) { if (meshTarget.cachedId!=meshTarget.gameObject.GetInstanceID()) meshTarget = PlaygroundParticlesC.NewWorldObject (meshTarget.gameObject.transform); if (meshTarget.mesh!=null) { meshTargetMatrix.SetTRS(meshTarget.transform.position, meshTarget.transform.rotation, meshTarget.transform.localScale); if (meshTargetIsProcedural) UpdateMeshTarget(); } if (meshTarget.initialized && (targetSortingList==null || targetSortingList.Length!=meshTarget.vertexPositions.Length || previousTargetSorting!=targetSorting)) TargetSorting(); } } else if (type==MANIPULATORPROPERTYTYPEC.SkinnedMeshTarget) { if (skinnedMeshTarget.gameObject!=null) { if (skinnedMeshTarget.cachedId!=skinnedMeshTarget.gameObject.GetInstanceID() || !skinnedMeshTarget.initialized) { skinnedMeshTarget = PlaygroundParticlesC.NewSkinnedWorldObject (skinnedMeshTarget.gameObject.transform); } if (skinnedMeshTarget.initialized) { if (meshTargetIsProcedural) UpdateSkinnedMeshTarget(); skinnedMeshTarget.BoneUpdate(); PlaygroundC.RunAsync(()=>{ skinnedMeshTarget.Update(); }); if (targetSortingList==null || targetSortingList.Length!=skinnedMeshTarget.vertexPositions.Length || previousTargetSorting!=targetSorting) TargetSorting(); } } } else if (type==MANIPULATORPROPERTYTYPEC.StateTarget) { if (!stateTarget.initialized && (stateTarget.stateMesh!=null || stateTarget.stateTexture!=null) && stateTarget.stateTransform!=null) { stateTarget.Initialize(); } else if (stateTarget.initialized && stateTarget.stateTransform!=null) { stateTarget.stateTransformMx.SetTRS(stateTarget.stateTransform.position, stateTarget.stateTransform.rotation, stateTarget.stateTransform.localScale); } if (stateTarget.initialized && (targetSortingList==null || targetSortingList.Length!=stateTarget.positionLength || previousTargetSorting!=targetSorting)) TargetSorting(); } else if (type==MANIPULATORPROPERTYTYPEC.SplineTarget) { splineTargetIsReady = splineTarget!=null&&splineTarget.IsReady(); } else if (type==MANIPULATORPROPERTYTYPEC.Turbulence) { if (turbulenceSimplex==null) turbulenceSimplex = new SimplexNoise(); } else if (type==MANIPULATORPROPERTYTYPEC.Math) { } }
/// <summary> /// Prepares all values for calculation which is not thread-safe. /// </summary> /// <returns><c>true</c>, if threaded calculations was prepared, <c>false</c> otherwise.</returns> public bool PrepareThreadedCalculations() { // Component disabled? if (!enabled) return false; // Auto-Pause (start/stop calculation when particle system is out of view. if (pauseCalculationWhenInvisible) { bool skipFrustumCheck = false; #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying) { calculate = true; skipFrustumCheck = true; } #endif if (!skipFrustumCheck && Camera.main!=null && PlaygroundC.frustumPlanes!=null) { bool shouldRender = GeometryUtility.TestPlanesAABB(PlaygroundC.frustumPlanes, new Bounds(calculationTriggerTransform==null?particleSystemTransform.position+calculationTriggerOffset:calculationTriggerTransform.position+calculationTriggerOffset, calculationTriggerSize)); if (!shouldRender && calculate && !particleSystemRenderer.isVisible) { calculate = false; #if UNITY_EDITOR if (!didHierarchyRepaint) UnityEditor.EditorApplication.RepaintHierarchyWindow(); didHierarchyRepaint = true; #endif return false; } else if (shouldRender && !calculate) { calculate = true; #if UNITY_EDITOR if (!didHierarchyRepaint) UnityEditor.EditorApplication.RepaintHierarchyWindow(); didHierarchyRepaint = true; #endif if (prewarm) {Start(); return false;} else SetParticleTimeNow (thisInstance); } } } else if (!calculate) { calculate = true; #if UNITY_EDITOR if (!didHierarchyRepaint) UnityEditor.EditorApplication.RepaintHierarchyWindow(); didHierarchyRepaint = true; #endif if (prewarm) {Start(); return false;} else SetParticleTimeNow (thisInstance); } if (!calculate) return false; // Has the calculation been paused previously? if (cameFromNonCalculatedFrame && hasActiveParticles) { StartCoroutine(Boot()); cameFromNonCalculatedFrame = false; return false; } // Apply locked position if (applyLockPosition) { if (lockPositionIsLocal) particleSystemTransform.localPosition = lockPosition; else particleSystemTransform.position = lockPosition; } // Apply locked rotation if (applyLockRotation) { if (lockRotationIsLocal) particleSystemTransform.localRotation = Quaternion.Euler(lockRotation); else particleSystemTransform.rotation = Quaternion.Euler(lockRotation); } // Apply locked scale if (applyLockScale) particleSystemTransform.localScale = lockScale; // Update active particle check hasActiveParticles = !threadHadNoActiveParticles || emit&&loop&&particleCount>0; if (!hasActiveParticles) { if (disableOnDone) queueEmissionHalt = true; } realSimulationTime = particleTimescale*Time.timeScale; cancelDeltaPositioningOnSync = false; // Prepare Source positions if (PlaygroundC.reference.IsDoneThread() && isDoneThread) { stRot = Quaternion.identity; stDir = new Vector3(); } localSpace = (shurikenParticleSystem.simulationSpace == ParticleSystemSimulationSpace.Local); overflow = (overflowOffset!=Vector3.zero); skinnedWorldObjectReady = false; renderModeStretch = particleSystemRenderer2.renderMode==ParticleSystemRenderMode.Stretch; particleSystemRotation = particleSystemTransform.rotation; particleSystemInverseRotation = particleSystemRotation; particleSystemInverseRotation.x = -particleSystemInverseRotation.x; particleSystemInverseRotation.y = -particleSystemInverseRotation.y; particleSystemInverseRotation.z = -particleSystemInverseRotation.z; particleSystemInverseRotation.w = -particleSystemInverseRotation.w; // Prepare turbulence if (!onlySourcePositioning && !onlyLifetimePositioning && turbulenceType!=TURBULENCETYPE.None) { if (turbulenceType==TURBULENCETYPE.Simplex && turbulenceSimplex==null) turbulenceSimplex = new SimplexNoise(); } if (emit) { switch (source) { case SOURCEC.Script: break; case SOURCEC.State: if (states.Count>0) { if (activeState>states.Count-1) activeState = states.Count-1; if (activeState<0) activeState = 0; if (states[activeState].stateTransform!=null) { if (isDoneThread) { if (!states[activeState].initialized) states[activeState].Initialize(); stRot = states[activeState].stateTransform.rotation; states[activeState].UpdateMatrix(localSpace); } if (localSpace && (states[activeState].stateTransform.parent==particleSystemTransform || states[activeState].stateTransform==particleSystemTransform) && isDoneThread) { cancelDeltaPositioningOnSync = true; stRot = Quaternion.Euler (Vector3.zero); } } } else return false; break; case SOURCEC.Transform: // Handle the availability of Playground Transforms (list of transform wrapper classes). // The single sourceTransform is an old method which needs to be copied over if available. if (sourceTransforms==null) { sourceTransforms = new List<PlaygroundTransformC>(); } if (sourceTransforms.Count==0) { sourceTransforms.Add(new PlaygroundTransformC()); sourceTransforms[0].transform = sourceTransform!=null?sourceTransform:particleSystemTransform; } if (isDoneThread) { for (int i = 0; i<sourceTransforms.Count; i++) { if (!sourceTransforms[i].Update()) return false; if (IsLocalSpace()) { psTransformNum = -1; sourceTransforms[i].SetLocalPosition(particleSystemTransform); sourceTransforms[i].SetPostitionAsLocal(); if (sourceTransforms[i].IsSameAs (particleSystemTransform)) { sourceTransforms[i].SetZeroRotation(); psTransformNum = i; } } } } if (isDoneThread) { stRot = sourceTransform.rotation; } if (localSpace && sourceTransform==particleSystemTransform && isDoneThread) { cancelDeltaPositioningOnSync = true; stRot = Quaternion.Euler (Vector3.zero); } break; case SOURCEC.WorldObject: // Handle vertex data in active World Object if (worldObject.gameObject!=null) { if (worldObject.gameObject.GetInstanceID()!=worldObject.cachedId || !worldObject.initialized) worldObject = NewWorldObject(worldObject.gameObject.transform); if (worldObject.mesh!=null) { if (isDoneThread) { stRot = worldObject.transform.transform.rotation; } if (localSpace && isDoneThread) { cancelDeltaPositioningOnSync = true; stRot = Quaternion.Euler (Vector3.zero); } worldObject.UpdateMatrix(localSpace); worldObject.updateNormals = worldObjectUpdateNormals; if (worldObjectUpdateVertices) worldObject.Update(); } else return false; } else return false; break; case SOURCEC.SkinnedWorldObject: // Handle vertex data in active Skinned World Object if (skinnedWorldObject.gameObject!=null) { if (skinnedWorldObject.gameObject.GetInstanceID()!=skinnedWorldObject.cachedId) { skinnedWorldObject = NewSkinnedWorldObject(skinnedWorldObject.gameObject.transform, skinnedWorldObject.downResolution); } } skinnedWorldObjectReady = skinnedWorldObject.gameObject!=null && skinnedWorldObject.mesh!=null; if (PlaygroundC.reference.skinnedMeshThreadMethod==ThreadMethodComponent.OneForAll && PlaygroundC.reference.IsFirstUnsafeAutomaticFrames() && !PlaygroundC.reference.IsDoneThreadSkinnedMeshes()) return false; if (skinnedWorldObjectReady) { if (isDoneThread) { stRot = skinnedWorldObject.transform.rotation; stDir = skinnedWorldObject.transform.TransformDirection (overflowOffset); } skinnedWorldObject.updateNormals = worldObjectUpdateNormals; if (Time.frameCount%PlaygroundC.skinnedUpdateRate==0) { if (worldObjectUpdateVertices) skinnedWorldObject.MeshUpdate(); skinnedWorldObject.BoneUpdate(); // Forced update for skinned mesh vertices on main-thread if (forceSkinnedMeshUpdateOnMainThread) { skinnedWorldObject.Update(); } } } else return false; break; case SOURCEC.Paint: if (paint.initialized) { if (isDoneThread) { stRot = particleSystemTransform.rotation; } if (paint.positionLength>0) { for (int p = 0; p<particleCache.Length; p++) { paint.Update(p); } } else return false; } else { paint.Initialize (); return false; } break; case SOURCEC.Projection: if (projection.projectionTexture!=null && projection.projectionTransform!=null) { if (!projection.initialized) projection.Initialize(); stRot = projection.projectionTransform.rotation; if (localSpace) shurikenParticleSystem.simulationSpace = ParticleSystemSimulationSpace.World; if (projection.liveUpdate || !projection.hasRefreshed) { projection.UpdateSource(); projection.Update(); stDir = projection.projectionTransform.TransformDirection (overflowOffset); projection.hasRefreshed = true; } } else return false; break; case SOURCEC.Spline: if (splines.Count>0) { for (int i = 0; i<splines.Count; i++) if (splines[i]==null || !splines[i].enabled || !splines[i].IsReady()) return false; if (isDoneThread) { stRot = particleSystemTransform.rotation; if (localSpace) { cancelDeltaPositioningOnSync = true; stRot = Quaternion.Euler (Vector3.zero); } } } else return false; break; } } // Collision detection (runs on main-thread) if (collision) Collisions(thisInstance); // Prepare Particle colors stateReadyForTextureColor = (source==SOURCEC.State && states[activeState].stateTexture!=null && states[activeState].colorLength>0); hasEventManipulatorLocal = false; hasEventManipulatorGlobal = false; hasGlobalAffectingManipulators = false; manipulatorEventCount = 0; thisLayer = particleSystemGameObject.layer; // Prepare Local Manipulators for (int m = 0; m<manipulators.Count; m++) { manipulators[m].Update(); manipulators[m].transform.SetLocalPosition(particleSystemTransform); manipulators[m].SetLocalTargetsPosition(particleSystemTransform); if (manipulators[m].trackParticles) { hasEventManipulatorLocal = true; manipulatorEventCount++; } } // Prepare Global Manipulators from this local space, bundle the thread call in case any Global Manipulator is tracking particles if (PlaygroundC.reference.HasEnabledGlobalManipulators()) { for (int m = 0; m<PlaygroundC.reference.manipulators.Count; m++) { if ((PlaygroundC.reference.manipulators[m].affects.value & 1<<GetLayer())!=0) { hasGlobalAffectingManipulators = true; PlaygroundC.reference.manipulators[m].transform.SetLocalPosition(particleSystemTransform); if (PlaygroundC.reference.manipulators[m].trackParticles && PlaygroundC.reference.threadMethod!=ThreadMethod.NoThreads) { threadMethod = ThreadMethodLocal.OneForAll; hasEventManipulatorGlobal = true; manipulatorEventCount++; } } } } hasSeveralManipulatorEvents = (manipulatorEventCount>1); // Prepare events hasEvent = events.Count>0; hasTimerEvent = false; if (hasEvent) { for (int i = 0; i<events.Count; i++) { events[i].Initialize(); if (events[i].initializedTarget && events[i].broadcastType!=EVENTBROADCASTC.EventListeners) if (!events[i].target.eventControlledBy.Contains (thisInstance)) events[i].target.eventControlledBy.Add (thisInstance); if (events[i].eventType==EVENTTYPEC.Time && ((events[i].broadcastType!=EVENTBROADCASTC.EventListeners && events[i].initializedTarget) || events[i].broadcastType==EVENTBROADCASTC.EventListeners && events[i].initializedEvent)) { hasTimerEvent = events[i].UpdateTime(); } } } // All good! Next step is to send all particles to calculation. return true; }
/// <summary> /// Gets the running simplex algorithm. /// </summary> /// <returns>The running simplex algorithm.</returns> public SimplexNoise GetSimplex() { if (turbulenceSimplex==null) turbulenceSimplex = new SimplexNoise(); return turbulenceSimplex; }
public static void Turbulence(PlaygroundParticlesC playgroundParticles, SimplexNoise turbulenceSimplex, int p, float t, TURBULENCETYPE turbulenceType, float turbulenceTimeScale, float turbulenceScale, float turbulenceStrength, bool turbulenceApplyLifetimeStrength, AnimationCurve turbulenceLifetimeStrength) { float turbulenceStrengthMultiplier = 1f; float zeroFixX = 1f; float zeroFixY = 2f; float zeroFixZ = 3f; if (playgroundParticles.playgroundCache.simulate[p] && playgroundParticles.playgroundCache.position[p].y != PlaygroundC.initialTargetPosition.y) { if (turbulenceType==TURBULENCETYPE.Simplex) { // Simplex Noise if (turbulenceTimeScale>0) { if (playgroundParticles.turbulenceApplyLifetimeStrength) turbulenceStrengthMultiplier = playgroundParticles.turbulenceLifetimeStrength.Evaluate (Mathf.Clamp01(playgroundParticles.playgroundCache.life[p]/((playgroundParticles.playgroundCache.death[p]-playgroundParticles.playgroundCache.birth[p])-playgroundParticles.playgroundCache.lifetimeSubtraction[p]))); if (turbulenceStrengthMultiplier>0) { if (!playgroundParticles.axisConstraints.x) playgroundParticles.playgroundCache.velocity[p].x += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale, playgroundParticles.localTime*turbulenceTimeScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.y) playgroundParticles.playgroundCache.velocity[p].y += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale, playgroundParticles.localTime*turbulenceTimeScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.z) playgroundParticles.playgroundCache.velocity[p].z += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale, playgroundParticles.localTime*turbulenceTimeScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; } } else { if (turbulenceStrengthMultiplier>0) { if (!playgroundParticles.axisConstraints.x) playgroundParticles.playgroundCache.velocity[p].x += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.y) playgroundParticles.playgroundCache.velocity[p].y += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.z) playgroundParticles.playgroundCache.velocity[p].z += (float)turbulenceSimplex.noise( (playgroundParticles.playgroundCache.position[p].z+zeroFixZ)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].x+zeroFixX)*turbulenceScale, (playgroundParticles.playgroundCache.position[p].y+zeroFixY)*turbulenceScale )*turbulenceStrength*t*turbulenceStrengthMultiplier; } } } else { // Perlin Noise if (playgroundParticles.turbulenceStrength>0) { if (playgroundParticles.turbulenceApplyLifetimeStrength) turbulenceStrengthMultiplier = playgroundParticles.turbulenceLifetimeStrength.Evaluate (Mathf.Clamp01(playgroundParticles.playgroundCache.life[p]/((playgroundParticles.playgroundCache.death[p]-playgroundParticles.playgroundCache.birth[p])-playgroundParticles.playgroundCache.lifetimeSubtraction[p]))); if (turbulenceStrengthMultiplier>0) { if (!playgroundParticles.axisConstraints.x) playgroundParticles.playgroundCache.velocity[p].x += (Mathf.PerlinNoise ( playgroundParticles.localTime*turbulenceTimeScale, playgroundParticles.playgroundCache.position[p].z*turbulenceScale )-.5f)*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.y) playgroundParticles.playgroundCache.velocity[p].y += (Mathf.PerlinNoise ( playgroundParticles.localTime*turbulenceTimeScale, playgroundParticles.playgroundCache.position[p].x*turbulenceScale )-.5f)*turbulenceStrength*t*turbulenceStrengthMultiplier; if (!playgroundParticles.axisConstraints.z) playgroundParticles.playgroundCache.velocity[p].z += (Mathf.PerlinNoise ( playgroundParticles.localTime*turbulenceTimeScale, playgroundParticles.playgroundCache.position[p].y*turbulenceScale )-.5f)*turbulenceStrength*t*turbulenceStrengthMultiplier; } } } } }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MonoBehaviours ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Awake () { if (isSnapshot) return; // Make sure all references exists CheckReferences(); // Make sure that state data is initialized for (int x = 0; x<states.Count; x++) states[x].Initialize(); // Initialize if (worldObject!=null && worldObject.transform!=null) worldObject.Initialize(); if (skinnedWorldObject!=null && skinnedWorldObject.transform!=null) skinnedWorldObject.Initialize(); if (projection!=null && projection.projectionTexture) projection.Initialize(); if (manipulators.Count>0) { for (int i = 0; i<manipulators.Count; i++) manipulators[i].Update(); } internalRandom01 = new System.Random(); internalRandom02 = new System.Random(); internalRandom03 = new System.Random(); turbulenceSimplex = new SimplexNoise(); eventParticle = new PlaygroundEventParticle(); if (PlaygroundC.reference!=null) { #if UNITY_EDITOR if (isSnapshot && !PlaygroundC.reference.showSnapshotsInHierarchy) { gameObject.hideFlags = HideFlags.HideInHierarchy; return; } #endif if (isSnapshot) return; if (!PlaygroundC.reference.particleSystems.Contains(this)) PlaygroundC.reference.particleSystems.Add(this); if (particleSystemTransform.parent==null && PlaygroundC.reference.autoGroup) particleSystemTransform.parent = PlaygroundC.referenceTransform; } // Reset event controlled by-list, this will be refreshed first calculation eventControlledBy = new List<PlaygroundParticlesC>(); }
/// <summary> /// Prepares all values for calculation which is not thread-safe. /// </summary> /// <returns><c>true</c>, if threaded calculations was prepared, <c>false</c> otherwise.</returns> public bool PrepareThreadedCalculations() { // Component disabled? if (!enabled) return false; // Has the calculation been paused previously? if (cameFromNonCalculatedFrame && hasActiveParticles) { StartCoroutine(Boot()); cameFromNonCalculatedFrame = false; return false; } // Apply locked position if (applyLockPosition) { if (lockPositionIsLocal) particleSystemTransform.localPosition = lockPosition; else particleSystemTransform.position = lockPosition; } // Apply locked rotation if (applyLockRotation) { if (lockRotationIsLocal) particleSystemTransform.localRotation = Quaternion.Euler(lockRotation); else particleSystemTransform.rotation = Quaternion.Euler(lockRotation); } // Apply locked scale if (applyLockScale) particleSystemTransform.localScale = lockScale; // Set delta time t = (localDeltaTime*particleTimescale); // Update active particle check hasActiveParticles = !threadHadNoActiveParticles; if (!hasActiveParticles) { if (disableOnDone) queueEmissionHalt = true; } // Prepare Source positions if (PlaygroundC.reference.IsDoneThread() && isDoneThread) { stPos = Vector3.zero; stRot = Quaternion.identity; stSca = new Vector3(1f, 1f, 1f); stDir = new Vector3(); } localSpace = (shurikenParticleSystem.simulationSpace == ParticleSystemSimulationSpace.Local); overflow = (overflowOffset!=Vector3.zero); skinnedWorldObjectReady = false; renderModeStretch = particleSystemRenderer2.renderMode==ParticleSystemRenderMode.Stretch; particleSystemInverseRotation = particleSystemTransform.rotation; // Prepare turbulence if (!onlySourcePositioning && !onlyLifetimePositioning && turbulenceStrength>0 && turbulenceType!=TURBULENCETYPE.None) { if (turbulenceType==TURBULENCETYPE.Simplex && turbulenceSimplex==null) turbulenceSimplex = new SimplexNoise(); } if (emit) { switch (source) { case SOURCEC.Script: break; case SOURCEC.State: if (states.Count>0) { if (states[activeState].stateTransform!=null) { if (isDoneThread) { if (!states[activeState].initialized) states[activeState].Initialize(); stPos = states[activeState].stateTransform.position; stRot = states[activeState].stateTransform.rotation; stSca = states[activeState].stateTransform.localScale; } if (localSpace && (states[activeState].stateTransform.parent==particleSystemTransform || states[activeState].stateTransform==particleSystemTransform) && isDoneThread) { stPos = Vector3.zero; stRot = Quaternion.Euler (Vector3.zero); } } } else return false; break; case SOURCEC.Transform: if (isDoneThread) { stPos = sourceTransform.position; stRot = sourceTransform.rotation; stSca = sourceTransform.localScale; } if (localSpace && sourceTransform==particleSystemTransform && isDoneThread) { stPos = Vector3.zero; stRot = Quaternion.Euler (Vector3.zero); } break; case SOURCEC.WorldObject: // Handle vertex data in active World Object if (worldObject.gameObject!=null) { if (worldObject.gameObject.GetInstanceID()!=worldObject.cachedId || !worldObject.initialized) worldObject = NewWorldObject(worldObject.gameObject.transform); if (worldObject.mesh!=null) { if (isDoneThread) { stPos = worldObject.transform.transform.position; stRot = worldObject.transform.transform.rotation; stSca = worldObject.transform.transform.localScale; } if (localSpace && isDoneThread) { stPos = Vector3.zero; stRot = Quaternion.Euler (Vector3.zero); } worldObject.updateNormals = worldObjectUpdateNormals; if (worldObjectUpdateVertices) worldObject.Update(); } else return false; } else return false; break; case SOURCEC.SkinnedWorldObject: // Handle vertex data in active Skinned World Object if (skinnedWorldObject.gameObject!=null) { if (skinnedWorldObject.gameObject.GetInstanceID()!=skinnedWorldObject.cachedId) skinnedWorldObject = NewSkinnedWorldObject(skinnedWorldObject.gameObject.transform, skinnedWorldObject.downResolution); } skinnedWorldObjectReady = skinnedWorldObject.gameObject!=null && skinnedWorldObject.mesh!=null; if (PlaygroundC.reference.skinnedMeshThreadMethod==ThreadMethodComponent.OneForAll && PlaygroundC.reference.IsFirstUnsafeAutomaticFrames() && !PlaygroundC.reference.IsDoneThreadSkinnedMeshes()) return false; if (skinnedWorldObjectReady) { if (isDoneThread) { stPos = skinnedWorldObject.transform.position; stRot = skinnedWorldObject.transform.rotation; stSca = skinnedWorldObject.transform.localScale; stDir = skinnedWorldObject.transform.TransformDirection (overflowOffset); } skinnedWorldObject.updateNormals = worldObjectUpdateNormals; if (Time.frameCount%PlaygroundC.skinnedUpdateRate==0) { if (worldObjectUpdateVertices) skinnedWorldObject.MeshUpdate(); skinnedWorldObject.BoneUpdate(); } } else return false; break; case SOURCEC.Paint: if (paint.initialized) { if (isDoneThread) { stPos = particleSystemTransform.position; stRot = particleSystemTransform.rotation; stSca = particleSystemTransform.localScale; } if (paint.positionLength>0) { for (int p = 0; p<particleCache.Length; p++) { paint.Update(p); } } else return false; } else { paint.Initialize (); return false; } break; case SOURCEC.Projection: if (projection.projectionTexture!=null && projection.projectionTransform!=null) { if (!projection.initialized) projection.Initialize(); stPos = projection.projectionTransform.position; stRot = projection.projectionTransform.rotation; stSca = projection.projectionTransform.localScale; if (localSpace) shurikenParticleSystem.simulationSpace = ParticleSystemSimulationSpace.World; if (projection.liveUpdate || !projection.hasRefreshed) { projection.UpdateSource(); projection.Update(); stDir = projection.projectionTransform.TransformDirection (overflowOffset); projection.hasRefreshed = true; } } else return false; break; } } // Collision detection (runs on main-thread) if (collision) Collisions(thisInstance); // Sync positions to main-thread if (syncPositionsOnMainThread) { if (particleCache.Length!=playgroundCache.position.Length) return false; for (int p = 0; p<particleCount; p++) { particleCache[p].position = playgroundCache.position[p]; } } // Prepare Particle colors stateReadyForTextureColor = (source==SOURCEC.State && states[activeState].stateTexture!=null); hasEventManipulatorLocal = false; hasEventManipulatorGlobal = false; manipulatorEventCount = 0; // Prepare local manipulators for (int m = 0; m<manipulators.Count; m++) { manipulators[m].Update(); manipulators[m].transform.SetLocalPosition(particleSystemTransform); manipulators[m].SetLocalTargetsPosition(particleSystemTransform); manipulators[m].willAffect = true; if (manipulators[m].trackParticles) { hasEventManipulatorLocal = true; manipulatorEventCount++; } } // Prepare global manipulators from this local space for (int m = 0; m<PlaygroundC.reference.manipulators.Count; m++) { PlaygroundC.reference.manipulators[m].willAffect = ((PlaygroundC.reference.manipulators[m].affects.value & 1<<particleSystemGameObject.layer)!=0); PlaygroundC.reference.manipulators[m].transform.SetLocalPosition(particleSystemTransform); if (PlaygroundC.reference.manipulators[m].trackParticles) { hasEventManipulatorGlobal = true; manipulatorEventCount++; } } hasSeveralManipulatorEvents = (manipulatorEventCount>1); // Prepare events hasEvent = events.Count>0; hasTimerEvent = false; if (hasEvent) { for (int i = 0; i<events.Count; i++) { events[i].Initialize(); if (events[i].initializedTarget && events[i].broadcastType!=EVENTBROADCASTC.EventListeners) if (!events[i].target.eventControlledBy.Contains (thisInstance)) events[i].target.eventControlledBy.Add (thisInstance); if (events[i].eventType==EVENTTYPEC.Time && ((events[i].broadcastType!=EVENTBROADCASTC.EventListeners && events[i].initializedTarget) || events[i].broadcastType==EVENTBROADCASTC.EventListeners && events[i].initializedEvent)) { hasTimerEvent = events[i].UpdateTime(); } } } // All good! Next step is to send all particles to calculation. return true; }