// CALCULATE FINAL POSITION // // public void CalculateFinalPosition() { foreach (Pool <ParticleMarker> .Node node in particleMarkers.ActiveNodes) { // We calculate velocity coming from direct positioning. Vector4 velocityFromPosition = (blueprint.positionStack.values[node.NodeIndex] - blueprint.positionStack.oldValues[node.NodeIndex]) / deltaTime; // Since we have no need for the old value anymore, we update it. blueprint.positionStack.oldValues[node.NodeIndex] = blueprint.positionStack.values[node.NodeIndex]; // We factor in velocity coming from the velocity stack. blueprint.positionStack.values[node.NodeIndex] += AmpsHelpers.ConvertVector3Vector4(velocityAccumulators[node.NodeIndex], 0); // Update velocity data with the velocity change coming from direct positioning. blueprint.velocityStack.values[node.NodeIndex] += velocityFromPosition; // We calculate acceleration coming from direct velocity setting plus direct positioning. Vector4 accelerationFromVelocity = (blueprint.velocityStack.values[node.NodeIndex] - blueprint.velocityStack.oldValues[node.NodeIndex]) / deltaTime; // Since we have no need for the old value anymore, we update it. blueprint.velocityStack.oldValues[node.NodeIndex] = blueprint.velocityStack.values[node.NodeIndex]; // Update acceleration data with some smoothing. blueprint.accelerationStack.values[node.NodeIndex] = Vector4.Lerp(blueprint.accelerationStack.oldValues[node.NodeIndex], blueprint.accelerationStack.values[node.NodeIndex] + accelerationFromVelocity, Mathf.Lerp(100, 0, emitterModule.accelerationNoiseSmoothing.constant) * deltaTime); // We store the current values for later use. blueprint.accelerationStack.oldValues[node.NodeIndex] = blueprint.accelerationStack.values[node.NodeIndex]; } }
// ACCUMULATE VELOCITY // // public void AccumulateVelocity() { foreach (Pool <ParticleMarker> .Node node in particleMarkers.ActiveNodes) { blueprint.velocityStack.values[node.NodeIndex] += AmpsHelpers.ConvertVector3Vector4(accelerationAccumulators[node.NodeIndex], 0); velocityAccumulators[node.NodeIndex] += AmpsHelpers.ConvertVector4Vector3(blueprint.velocityStack.values[node.NodeIndex]) * deltaTime; } }
public int randomSeed = 0; // A property specific random seed; // CONVERT COORDINATE SYSTEM // // // TODO: Move it to AmpsHelpers. public Vector4 ConvertCoordinateSystem(Vector4 v, int particleIndex) { Vector3 returnValue = v; switch (coordSystem) { case AmpsHelpers.eCoordSystems.World: //switch (coordSystemConversionMode) //{ // case eCoordSystemConversionMode.AsPosition: // break; // case eCoordSystemConversionMode.AsRotation: // break; // case eCoordSystemConversionMode.AsVelocity: // break; // case eCoordSystemConversionMode.AsScale: // break; //} break; case AmpsHelpers.eCoordSystems.Emitter: switch (coordSystemConversionMode) { case eCoordSystemConversionMode.AsPosition: returnValue += ownerBlueprint.ownerEmitter.transform.position; returnValue = AmpsHelpers.RotateAroundPoint(returnValue, ownerBlueprint.ownerEmitter.emitterPosition, ownerBlueprint.ownerEmitter.transform.rotation); break; case eCoordSystemConversionMode.AsRotation: returnValue += ownerBlueprint.ownerEmitter.transform.rotation.eulerAngles; break; case eCoordSystemConversionMode.AsVelocity: returnValue = ownerBlueprint.ownerEmitter.emitterMatrixPositionZero.MultiplyPoint3x4(returnValue); break; case eCoordSystemConversionMode.AsScale: returnValue.x *= ownerBlueprint.ownerEmitter.transform.lossyScale.x; returnValue.y *= ownerBlueprint.ownerEmitter.transform.lossyScale.y; returnValue.z *= ownerBlueprint.ownerEmitter.transform.lossyScale.z; break; } break; } return(AmpsHelpers.ConvertVector3Vector4(returnValue, 0)); }
// EVALUATE // // // Evaluate when particle specific data IS available. override public void Evaluate(ref Vector4[] input) { Vector4 finalValue = Vector4.zero; int particleIndex; for (int i = 0; i < ownerBlueprint.ownerEmitter.activeParticleIndices.Length; i++) { particleIndex = ownerBlueprint.ownerEmitter.activeParticleIndices[i]; if (ownerStack.isVector3Stack) { Vector3 v = new Vector3(input[particleIndex].x, input[particleIndex].y, input[particleIndex].z); v = v.normalized; finalValue = AmpsHelpers.ConvertVector3Vector4(v, 0); } else { finalValue = input[particleIndex].normalized; } input[particleIndex] = Blend(input[particleIndex], finalValue, weight.GetValue(particleIndex)); } }
public int randomSeed = 0; // A curve specific random seed; // GET CURVE INPUT // // public float GetCurveInput(AmpsBlueprint ownerBlueprint, int particleIndex) { float returnValue = 0; Vector3 v3 = Vector3.zero; Vector4 v4 = Vector4.zero; //Matrix4x4 toMatrix = AmpsHelpers.identityMatrix; // Slightly faster than Matrix4x4.identity; v4 = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, curveInput); // The only need to work with conversion to emitter space as everything // is world relative by default. if (curveInputCoordSystem == AmpsHelpers.eCoordSystems.Emitter) { //toMatrix = ownerBlueprint.ownerEmitter.emitterMatrixFull; if (AmpsHelpers.isPositionInput(curveInput)) { v3 = AmpsHelpers.ConvertVector4Vector3(v4); v3 -= ownerBlueprint.ownerEmitter.transform.position; v3 = AmpsHelpers.RotateAroundPoint(v3, ownerBlueprint.ownerEmitter.emitterPosition, ownerBlueprint.ownerEmitter.transform.rotation); v4 = AmpsHelpers.ConvertVector3Vector4(v3, 0); } else if (AmpsHelpers.isRotationInput(curveInput)) { v3 = AmpsHelpers.ConvertVector4Vector3(v4); v3 += ownerBlueprint.ownerEmitter.transform.rotation.eulerAngles; v4 = AmpsHelpers.ConvertVector3Vector4(v3, 0); } else if (AmpsHelpers.isVelocityInput(curveInput)) { v3 = AmpsHelpers.ConvertVector4Vector3(v4); v3 += ownerBlueprint.ownerEmitter.emitterMatrixPositionZero.MultiplyPoint3x4(v3); v4 = AmpsHelpers.ConvertVector3Vector4(v3, 0); } else if (AmpsHelpers.isScaleInput(curveInput)) { v3 = AmpsHelpers.ConvertVector4Vector3(v4); v3.x *= ownerBlueprint.ownerEmitter.transform.lossyScale.x; v3.y *= ownerBlueprint.ownerEmitter.transform.lossyScale.y; v3.z *= ownerBlueprint.ownerEmitter.transform.lossyScale.z; v4 = AmpsHelpers.ConvertVector3Vector4(v3, 0); } } if (AmpsHelpers.isFloatInput(curveInput)) { returnValue = v4.x; } else { //if (AmpsHelpers.isPositionInput(curveInput)) v = toMatrix.MultiplyPoint3x4(v); //else v = toMatrix.MultiplyVector(v); switch (curveInputVectorComponent) { case AmpsHelpers.eVectorComponents.X: returnValue = v4.x; break; case AmpsHelpers.eVectorComponents.Y: returnValue = v4.y; break; case AmpsHelpers.eVectorComponents.Z: returnValue = v4.z; break; case AmpsHelpers.eVectorComponents.W: returnValue = v4.w; break; case AmpsHelpers.eVectorComponents.Mag: returnValue = new Vector3(v4.x, v4.y, v4.z).magnitude; break; } // TODO: Handle Color. } // Normalize input. float finalInputRangeMin = inputRangeMin; float finalInputRangeMax = inputRangeMax; if (isInputRangeRandom) { System.Random theRandom = new System.Random(ownerBlueprint.ownerEmitter.randomSeed + randomSeed + ownerBlueprint.ownerEmitter.particleIds[particleIndex]); finalInputRangeMin = Mathf.Lerp(inputRangeMin, inputRangeRandomMin, (float)theRandom.NextDouble()); finalInputRangeMax = Mathf.Lerp(inputRangeMax, inputRangeRandomMax, (float)theRandom.NextDouble()); } if (finalInputRangeMax - finalInputRangeMin == 0) { returnValue = 0; } else { returnValue = (returnValue - finalInputRangeMin) / (finalInputRangeMax - finalInputRangeMin); } return(returnValue); }