Example #1
0
        // EVALUATE //
        //
        // Evaluate when particle specific data is NOT available.
        override public void Evaluate(ref float input)
        {
            float output      = 0;
            float finalValueA = useStackValue.GetValue() ? input : valueA.GetValue();

            switch (condition.GetValue())
            {
            case (int)eConditions.Greater:
                if (finalValueA > valueB.GetValue())
                {
                    output = valueTrue.GetValue();
                }
                else
                {
                    output = valueFalse.GetValue();
                }
                break;

            case (int)eConditions.Less:
                if (finalValueA < valueB.GetValue())
                {
                    output = valueTrue.GetValue();
                }
                else
                {
                    output = valueFalse.GetValue();
                }
                break;

            case (int)eConditions.Equal:
                if (finalValueA == valueB.GetValue())
                {
                    output = valueTrue.GetValue();
                }
                else
                {
                    output = valueFalse.GetValue();
                }
                break;

            case (int)eConditions.NotEqual:
                if (finalValueA != valueB.GetValue())
                {
                    output = valueTrue.GetValue();
                }
                else
                {
                    output = valueFalse.GetValue();
                }
                break;
            }

            input = Blend(input, output, weight.GetValue());
        }
Example #2
0
        public DropdownData displayData;                // The function which fetches the string array to display in the dropdown control.
        // Since delegates are not serialized it will get it's value right before first
        // UI render.
                #endif

        // GET VALUE //
        //
        public int GetValue()
        {
            int returnValue = 0;

#if UNITY_EDITOR
            CheckReferences();
#endif

            switch (dataMode)
            {
            case eDataMode.Constant:
                returnValue = constant;
                break;

            case eDataMode.Reference:
                if (reference != null)
                {
                    DropdownProperty theReference = (DropdownProperty)reference.property;
                    returnValue = theReference.GetValue();
                }
                break;
            }

            return(returnValue);
        }
        // EVALUATE //
        //
        // Evaluate when particle specific data IS available.
        override public void Evaluate(ref Vector4[] input)
        {
            int particleIndex;

            for (int i = 0; i < ownerBlueprint.ownerEmitter.activeParticleIndices.Length; i++)
            {
                particleIndex = ownerBlueprint.ownerEmitter.activeParticleIndices[i];
                switch (conversionMode.GetValue())
                {
                case (int)eConversionModes.DirectionToRotation:
                    // TODO: Choose upvector.
                    Vector3 lookRotation = input[particleIndex];
                    if (lookRotation == Vector3.zero)
                    {
                        lookRotation.x = 0.00001f;
                    }
                    input[particleIndex] = Quaternion.LookRotation(lookRotation, Vector3.up).eulerAngles;
                    break;

                case (int)eConversionModes.RotationToDirection:
                    input[particleIndex] = Quaternion.Euler(input[particleIndex]) * Vector3.forward;
                    break;

                case (int)eConversionModes.HSVToRGB:
                    input[particleIndex] = AmpsHelpers.HSVAtoRGBA(input[particleIndex]);
                    break;

                case (int)eConversionModes.RGBToHSV:
                    input[particleIndex] = AmpsHelpers.RGBAtoHSVA(input[particleIndex]);
                    break;
                }
            }
        }
        // EVALUATE //
        //
        // Evaluate when particle specific data is NOT available.
        override public void Evaluate(ref float input)
        {
            Vector4 finalValue = untriggeredValue.GetValue();

            if (ownerBlueprint.ownerEmitter.emitterLoopTime < previousLoopTime)
            {
                currentTriggerCount = 0;
            }
            previousLoopTime = ownerBlueprint.ownerEmitter.emitterLoopTime;
            if (triggerToggle.GetValue() == false &&
                ownerBlueprint.ownerEmitter.emitterTime > lastTriggerTime + triggerDuration.GetValue())
            {
                isTriggered = false;
            }

            if (isTriggered)
            {
                switch ((eTriggerDataModes)triggerDataMode.GetValue())
                {
                case eTriggerDataModes.CustomValue:
                    finalValue = triggeredCustomValue.GetValue();
                    break;

                case eTriggerDataModes.EventData1:
                    finalValue = lastEventData.DataSlot1;
                    break;

                case eTriggerDataModes.EventData2:
                    finalValue = lastEventData.DataSlot2;
                    break;

                case eTriggerDataModes.EventData3:
                    finalValue = lastEventData.DataSlot3;
                    break;

                case eTriggerDataModes.EventData4:
                    finalValue = lastEventData.DataSlot4;
                    break;
                }
            }

            input = Blend(input, finalValue, weight.GetValue());
        }
        // MANAGE SAMPLING //
        //
        // Does the actual sampling.
        override public void ManageSampling(int particleIndex)
        {
            Vector3 v = Vector3.zero;
            bool    shouldIndeedSample = (particleIndex < 0 && ShouldSample()) || (particleIndex >= 0 && ShouldSample(particleIndex));

            // Leave if it's not time yet to sample.
            if (shouldIndeedSample == false)
            {
                return;
            }

            // INVALID SAMPLE: Referenced GameObject is not available.
            GameObject theGameObject = sampledObject.GetValue();

            if (theGameObject == null)
            {
                isValidSample[particleIndex] = false;
                return;
            }

            switch (sampledTransformElement.GetValue())
            {
            case (int)eTransformElements.Position:
                v = theGameObject.transform.position;
                break;

            case (int)eTransformElements.Rotation:
                v = theGameObject.transform.rotation.eulerAngles;
                break;

            case (int)eTransformElements.Scale:
                v = theGameObject.transform.localScale;
                break;
            }
            vectors[particleIndex] = new Vector4(v.x, v.y, v.z, 0);

            isValidSample[particleIndex] = true;
        }
Example #6
0
 // EVALUATE //
 //
 // Evaluate when particle specific data is NOT available.
 override public void Evaluate(ref float input)
 {
                 #if UNITY_EDITOR
     if (showCurrentStack.GetValue())
     {
         label.value = input.ToString("F3");
     }
     else
     {
         if (ownerBlueprint.ownerEmitter.exampleInputParticleIndex < 0)
         {
             return;
         }
         Vector4 v = AmpsHelpers.GetSystemProperty(ownerBlueprint, ownerBlueprint.ownerEmitter.exampleInputParticleIndex, (AmpsHelpers.eCurveInputs)property.GetValue());
         label.value = v.x.ToString("F3") + ", " +
                       v.y.ToString("F3") + ", " +
                       v.z.ToString("F3") + ", " +
                       v.w.ToString("F3");
     }
     moduleName.value = label.value;
                 #endif
 }
        // SHOULD SAMPLE //
        //
        // Check sampling condition when particle data IS available.
        public bool ShouldSample(int particleIndex)
        {
            bool  returnValue = false;
            float currentTime;

            // Get "currentTime" from the proper source.
            if (ownerStack.isParticleStack)
            {
                currentTime = ownerBlueprint.ownerEmitter.particleTimes[particleIndex];
            }
            else
            {
                currentTime = ownerBlueprint.ownerEmitter.emitterTime;
            }

            // Apply time offset if appropriate.
            if (samplerCondition.GetValue() == (int)eSamplerConditions.ByTime)
            {
                currentTime = currentTime - intervalOffset.GetValue();
                if (currentTime < 0)
                {
                    currentTime = 0;
                }
            }
            else if (samplerCondition.GetValue() == (int)eSamplerConditions.OnCreation &&
                     lastSampleTimes[particleIndex] < 0 &&
                     currentTime >= intervalOffset.GetValue())
            {
                lastSampleTimes[particleIndex] = currentTime;
                returnValue = true;
            }

            // We do a sample if we should on spawn and if the last sample timestamp is -1 i.e. no sample has been taken yet.
            if (sampleOnSpawn.GetValue() && lastSampleTimes[particleIndex] < 0)
            {
                lastSampleTimes[particleIndex] = currentTime;
                returnValue = true;
            }

            switch ((eSamplerConditions)samplerCondition.GetValue())
            {
            // AmpsHelpers.eSamplerConditions.OnCreation was handled above.

            case eSamplerConditions.ByTime:
                if (currentTime >= lastSampleTimes[particleIndex] + interval.GetValue())
                {
                    returnValue = true;
                    lastSampleTimes[particleIndex] = Mathf.Round(currentTime / interval.GetValue()) * interval.GetValue();
                }
                break;

            case eSamplerConditions.ByDirectValue:
                float theDirectValue = 0;

                if (ownerStack.isParticleStack)
                {
                    theDirectValue = directValue.GetValue(particleIndex);
                }
                else
                {
                    theDirectValue = directValue.GetValue();
                }

                if (theDirectValue >= 1)
                {
                    returnValue = true;
                    lastSampleTimes[particleIndex] = currentTime;
                }
                break;

            case eSamplerConditions.OnCollision:
                // True if collision occured on last update.
                // TODO: Implement collision.
                break;
            }

            return(returnValue);
        }
Example #8
0
        // MANAGE EVENT //
        //
        void ManageEvent(Vector4 input, bool isInputFloat, int particleIndex)
        {
            bool    shouldTriggerEvent = false;
            Vector4 rawProperty;
            bool    isRawPropertyFloat = isInputFloat;
            float   thePropertyValue   = 0;

            if (useCurrentStack.GetValue() == false)
            {
                rawProperty        = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)property.GetValue());
                isRawPropertyFloat = AmpsHelpers.isFloatInput((AmpsHelpers.eCurveInputs)property.GetValue());
            }
            else
            {
                rawProperty = input;
            }

            if (isRawPropertyFloat)
            {
                thePropertyValue = rawProperty.x;
            }
            else
            {
                switch (propertyVectorComponent.GetValue())
                {
                case (int)AmpsHelpers.eVectorComponents.X:
                    thePropertyValue = rawProperty.x;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Y:
                    thePropertyValue = rawProperty.y;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Z:
                    thePropertyValue = rawProperty.z;
                    break;

                case (int)AmpsHelpers.eVectorComponents.W:
                    thePropertyValue = rawProperty.w;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Mag:
                    thePropertyValue = new Vector3(rawProperty.x, rawProperty.y, rawProperty.z).magnitude;
                    break;
                }
            }

            switch (condition.GetValue())
            {
            case (int)eConditions.Greater:
                shouldTriggerEvent = thePropertyValue > value.GetValue();
                break;

            case (int)eConditions.Less:
                shouldTriggerEvent = thePropertyValue < value.GetValue();
                break;

            case (int)eConditions.Equal:
                shouldTriggerEvent = thePropertyValue == value.GetValue();
                break;

            case (int)eConditions.NotEqual:
                shouldTriggerEvent = thePropertyValue != value.GetValue();
                break;
            }

            if (shouldTriggerEvent)
            {
                AmpsEmitter[] childEmitters = ownerBlueprint.ownerEmitter.transform.GetComponentsInChildren <AmpsEmitter>();
                for (int i = 0; i < childEmitters.Length; i++)
                {
                    switch ((eActions)action.GetValue())
                    {
                    case eActions.ResetAndPlay:
                        childEmitters[i].Play();
                        break;

                    case eActions.PlayIfNotPlaying:
                        if (childEmitters[i].isStopped)
                        {
                            childEmitters[i].Play();
                        }
                        else if (childEmitters[i].isPaused)
                        {
                            childEmitters[i].Unpause();
                        }
                        break;

                    case eActions.Pause:
                        if (childEmitters[i].isPaused == false)
                        {
                            childEmitters[i].Pause();
                        }
                        break;

                    default:
                        break;
                    }
                }

                timeOfLastEvent = ownerBlueprint.ownerEmitter.emitterTime;
            }
        }
Example #9
0
        // EVALUATE //
        //
        override public void Evaluate()
        {
            Vector4    customVector;
            Vector3    position;
            Vector3    pivotOffset;
            Vector3    rotation;
            Quaternion quaternionRotation;
            Vector3    scale;
            Color      color;
            bool       shouldRecreateMesh;
            bool       shouldBeDoubleSided;
            Quaternion camFacingRotation;
            int        vertexIndexSteps;
            int        triangleIndexSteps;

            if (ownerBlueprint == null ||
                ownerBlueprint.ownerEmitter == null ||
                ownerBlueprint.ownerEmitter.particleMarkers == null)
            {
                return;                                                                                 // To fix null ref log spam after script rebuild.
            }
            if (finalMesh == null)
            {
                SoftReset();
            }

            ownerBlueprint.ownerEmitter.activeParticleIndices = ownerBlueprint.ownerEmitter.particleMarkers.GetActiveIndices();
            particleCount       = ownerBlueprint.ownerEmitter.activeParticleIndices.Length;
            shouldRecreateMesh  = (particleCount != lastParticleCount);
            shouldBeDoubleSided = isDoubleSided.GetValue();
            if (shouldBeDoubleSided)
            {
                vertexIndexSteps   = 8;
                triangleIndexSteps = 12;
            }
            else
            {
                vertexIndexSteps   = 4;
                triangleIndexSteps = 6;
            }
            // TODO: Investigate why this line fails at runtime around 2 * 4:
            //shouldRecreateMesh = triangles.Length != particleCount * vertexIndexSteps;

            if (shouldRecreateMesh)
            {
                finalMesh.Clear();

                vertices  = new Vector3[particleCount * vertexIndexSteps];
                normals   = new Vector3[particleCount * vertexIndexSteps];
                tangents  = new Vector4[particleCount * vertexIndexSteps];
                uvs       = new Vector2[particleCount * vertexIndexSteps];
                uv2s      = new Vector2[particleCount * vertexIndexSteps];
                colors    = new Color[particleCount * vertexIndexSteps];
                triangles = new int[particleCount * triangleIndexSteps];

                lastParticleCount = particleCount;
            }

            int particleIndex;

            for (int i = 0; i < ownerBlueprint.ownerEmitter.activeParticleIndices.Length; i++)
            {
                particleIndex = ownerBlueprint.ownerEmitter.activeParticleIndices[i];
                customVector  = ownerBlueprint.customVectorStack.values[particleIndex];

                position  = AmpsHelpers.ConvertVector4Vector3(ownerBlueprint.ownerEmitter.blueprint.positionStack.values[particleIndex]); // Raw position stack result.
                position  = AmpsHelpers.RotateAroundPoint(position, ownerBlueprint.ownerEmitter.transform.position, Quaternion.Inverse(ownerBlueprint.ownerEmitter.transform.rotation));
                position -= ownerBlueprint.ownerEmitter.emitterPosition;                                                                  // Compensating for emitter position, turning position world relative.

                pivotOffset = AmpsHelpers.ConvertVector4Vector3(ownerBlueprint.pivotOffsetStack.values[particleIndex]);

                rotation           = AmpsHelpers.ConvertVector4Vector3(ownerBlueprint.rotationStack.values[particleIndex]);       // Raw particle stack result.
                quaternionRotation = Quaternion.Inverse(ownerBlueprint.ownerEmitter.transform.rotation) * Quaternion.Euler(rotation);

                scale = AmpsHelpers.ConvertVector4Vector3(ownerBlueprint.scaleStack.values[particleIndex]);

                color = ownerBlueprint.colorStack.values[particleIndex];

                // Setting up the quad, particle is at the center.
                vertices[i * vertexIndexSteps]     = (position + pivotOffset) + (new Vector3(scale.x, scale.y, 0) / 2);
                vertices[i * vertexIndexSteps + 1] = (position + pivotOffset) + (new Vector3(-scale.x, scale.y, 0) / 2);
                vertices[i * vertexIndexSteps + 2] = (position + pivotOffset) + (new Vector3(-scale.x, -scale.y, 0) / 2);
                vertices[i * vertexIndexSteps + 3] = (position + pivotOffset) + (new Vector3(scale.x, -scale.y, 0) / 2);

                switch (orientation.GetValue())
                {
                case (int)eOrientation.Rotated:
                    // Rotating the (pivot offset) vertices around particle position.
                    vertices[i * vertexIndexSteps]     = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps], position, quaternionRotation);
                    vertices[i * vertexIndexSteps + 1] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 1], position, quaternionRotation);
                    vertices[i * vertexIndexSteps + 2] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 2], position, quaternionRotation);
                    vertices[i * vertexIndexSteps + 3] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 3], position, quaternionRotation);
                    break;

                case (int)eOrientation.CameraFacing:
                    camFacingRotation = Quaternion.LookRotation(ownerBlueprint.ownerEmitter.currentCameraTransform.forward, ownerBlueprint.ownerEmitter.currentCameraTransform.up);
                    camFacingRotation = Quaternion.Inverse(ownerBlueprint.ownerEmitter.transform.rotation) * camFacingRotation;
                    // TODO: Research if camera-particle position diff vector is better.

                    // Rotating all vertices around the center so the quad faces the camera.
                    vertices[i * vertexIndexSteps]     = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 1] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 1], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 2] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 2], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 3] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 3], position, camFacingRotation);
                    break;

                case (int)eOrientation.RotatedCameraFacing:
                    camFacingRotation = Quaternion.LookRotation(ownerBlueprint.ownerEmitter.currentCameraTransform.forward, ownerBlueprint.ownerEmitter.currentCameraTransform.up);
                    camFacingRotation = Quaternion.Inverse(ownerBlueprint.ownerEmitter.transform.rotation) * camFacingRotation;
                    camFacingRotation = camFacingRotation * Quaternion.Euler(rotation);

                    // Rotating all vertices around the center so the quad faces the camera.
                    vertices[i * vertexIndexSteps]     = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 1] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 1], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 2] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 2], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 3] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 3], position, camFacingRotation);
                    break;

                case (int)eOrientation.VectorAlignedCameraFacing:
                    //Vector3 upVector = Vector3.Normalize(alignmentVector.GetValue());
                    //Vector3 forwardVector = ownerBlueprint.ownerEmitter.currentCameraTransform.forward;
                    ////ownerBlueprint.ownerEmitter.currentCameraTransform.up;
                    //camFacingRotation = Quaternion.LookRotation(forwardVector, upVector);
                    ////camFacingRotation = Quaternion.Inverse(ownerBlueprint.ownerEmitter.transform.rotation) * camFacingRotation;

                    camFacingRotation = Quaternion.LookRotation(ownerBlueprint.ownerEmitter.currentCameraTransform.forward, Vector3.up);
                    Vector3 eulerRotation = camFacingRotation.eulerAngles;
                    eulerRotation.x   = 0;                              // Discard rotation around x.
                    eulerRotation.z   = 0;                              // Discard rotation around z.
                    camFacingRotation = Quaternion.Euler(eulerRotation);

                    // Rotating all vertices around the center so the quad faces the camera.
                    vertices[i * vertexIndexSteps]     = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 1] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 1], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 2] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 2], position, camFacingRotation);
                    vertices[i * vertexIndexSteps + 3] = AmpsHelpers.RotateAroundPoint(vertices[i * vertexIndexSteps + 3], position, camFacingRotation);
                    break;
                }

                if (shouldBeDoubleSided)
                {
                    vertices[i * vertexIndexSteps + 4] = vertices[i * vertexIndexSteps];
                    vertices[i * vertexIndexSteps + 5] = vertices[i * vertexIndexSteps + 1];
                    vertices[i * vertexIndexSteps + 6] = vertices[i * vertexIndexSteps + 2];
                    vertices[i * vertexIndexSteps + 7] = vertices[i * vertexIndexSteps + 3];
                }

                colors[i * vertexIndexSteps]     = color;
                colors[i * vertexIndexSteps + 1] = color;
                colors[i * vertexIndexSteps + 2] = color;
                colors[i * vertexIndexSteps + 3] = color;
                if (shouldBeDoubleSided)
                {
                    if ((eDoubleSidedColorMode)doubleSidedColorMode.GetValue() == eDoubleSidedColorMode.ColorStack)
                    {
                        colors[i * vertexIndexSteps + 4] = colors[i * vertexIndexSteps];
                        colors[i * vertexIndexSteps + 5] = colors[i * vertexIndexSteps + 1];
                        colors[i * vertexIndexSteps + 6] = colors[i * vertexIndexSteps + 2];
                        colors[i * vertexIndexSteps + 7] = colors[i * vertexIndexSteps + 3];
                    }
                    else
                    {
                        colors[i * vertexIndexSteps + 4] = customVector;
                        colors[i * vertexIndexSteps + 5] = customVector;
                        colors[i * vertexIndexSteps + 6] = customVector;
                        colors[i * vertexIndexSteps + 7] = customVector;
                    }
                }

                switch (normalMode.GetValue())
                {
                case (int)eNormalMode.Skip:
                    break;

                case (int)eNormalMode.Flat:
                    Vector3 calculatedNormal = Vector3.Cross((vertices[i * vertexIndexSteps + 2] - vertices[i * vertexIndexSteps]), (vertices[i * vertexIndexSteps + 1] - vertices[i * vertexIndexSteps]));
                    calculatedNormal = Vector3.Normalize(calculatedNormal);
                    normals[i * vertexIndexSteps]     = calculatedNormal;
                    normals[i * vertexIndexSteps + 1] = calculatedNormal;
                    normals[i * vertexIndexSteps + 2] = calculatedNormal;
                    normals[i * vertexIndexSteps + 3] = calculatedNormal;
                    break;
                }
                if (shouldBeDoubleSided)
                {
                    normals[i * vertexIndexSteps + 4] = normals[i * vertexIndexSteps] * -1;
                    normals[i * vertexIndexSteps + 5] = normals[i * vertexIndexSteps + 1] * -1;
                    normals[i * vertexIndexSteps + 6] = normals[i * vertexIndexSteps + 2] * -1;
                    normals[i * vertexIndexSteps + 7] = normals[i * vertexIndexSteps + 3] * -1;
                }

                switch (uv2Mode.GetValue())
                {
                case (int)eUV2Mode.Skip:
                    break;

                case (int)eUV2Mode.CustomVectorXY:
                    uv2s[i * vertexIndexSteps]     = new Vector2(customVector.x, customVector.y);
                    uv2s[i * vertexIndexSteps + 1] = new Vector2(customVector.x, customVector.y);
                    uv2s[i * vertexIndexSteps + 2] = new Vector2(customVector.x, customVector.y);
                    uv2s[i * vertexIndexSteps + 3] = new Vector2(customVector.x, customVector.y);
                    break;

                case (int)eUV2Mode.CustomVectorXYZW:                            // BUG: Doesn't really work...
                    Vector2 calculatedUv2 = Vector2.zero;
                    calculatedUv2.x                = AmpsHelpers.PackVector2(new Vector2(customVector.x, customVector.y));
                    calculatedUv2.y                = AmpsHelpers.PackVector2(new Vector2(customVector.z, customVector.w));
                    uv2s[i * vertexIndexSteps]     = calculatedUv2;
                    uv2s[i * vertexIndexSteps + 1] = calculatedUv2;
                    uv2s[i * vertexIndexSteps + 2] = calculatedUv2;
                    uv2s[i * vertexIndexSteps + 3] = calculatedUv2;
                    break;
                }
                if (shouldBeDoubleSided)
                {
                    uv2s[i * vertexIndexSteps + 4] = uv2s[i * vertexIndexSteps];
                    uv2s[i * vertexIndexSteps + 5] = uv2s[i * vertexIndexSteps + 1];
                    uv2s[i * vertexIndexSteps + 6] = uv2s[i * vertexIndexSteps + 2];
                    uv2s[i * vertexIndexSteps + 7] = uv2s[i * vertexIndexSteps + 3];
                }

                switch (tangentMode.GetValue())
                {
                case (int)eTangentMode.Skip:
                    break;

                case (int)eTangentMode.Generate:
                    //Vector3 rawTangent = Vector3.Normalize(vertices[i * 4 + 3] - vertices[i * 4 + 1]);
                    Vector3 rawTangent        = Vector3.Normalize(vertices[i * 4 + 0] - vertices[i * 4 + 1]);
                    Vector4 calculatedTangent = new Vector4(rawTangent.x, rawTangent.y, rawTangent.z, -1);
                    tangents[i * vertexIndexSteps]     = calculatedTangent;
                    tangents[i * vertexIndexSteps + 1] = calculatedTangent;
                    tangents[i * vertexIndexSteps + 2] = calculatedTangent;
                    tangents[i * vertexIndexSteps + 3] = calculatedTangent;
                    break;

                case (int)eTangentMode.CustomVectorXYZW:
                    tangents[i * vertexIndexSteps]     = customVector;
                    tangents[i * vertexIndexSteps + 1] = customVector;
                    tangents[i * vertexIndexSteps + 2] = customVector;
                    tangents[i * vertexIndexSteps + 3] = customVector;
                    break;
                }
                if (shouldBeDoubleSided)
                {
                    // TODO: Should it be multiplied by -1?
                    tangents[i * vertexIndexSteps + 4] = tangents[i * vertexIndexSteps];
                    tangents[i * vertexIndexSteps + 5] = tangents[i * vertexIndexSteps + 1];
                    tangents[i * vertexIndexSteps + 6] = tangents[i * vertexIndexSteps + 2];
                    tangents[i * vertexIndexSteps + 7] = tangents[i * vertexIndexSteps + 3];
                }


                if (shouldRecreateMesh)                 // Things go in here which don't change unless particle count changes.
                {
                    uvs[i * vertexIndexSteps]     = new Vector2(1, 1);
                    uvs[i * vertexIndexSteps + 1] = new Vector2(0, 1);
                    uvs[i * vertexIndexSteps + 2] = new Vector2(0, 0);
                    uvs[i * vertexIndexSteps + 3] = new Vector2(1, 0);
                    if (shouldBeDoubleSided)
                    {
                        uvs[i * vertexIndexSteps + 4] = new Vector2(1, 1);
                        uvs[i * vertexIndexSteps + 5] = new Vector2(0, 1);
                        uvs[i * vertexIndexSteps + 6] = new Vector2(0, 0);
                        uvs[i * vertexIndexSteps + 7] = new Vector2(1, 0);
                    }

                    //First triangle.
                    triangles[i * triangleIndexSteps]     = i * vertexIndexSteps;
                    triangles[i * triangleIndexSteps + 1] = i * vertexIndexSteps + 2;
                    triangles[i * triangleIndexSteps + 2] = i * vertexIndexSteps + 1;
                    //Second triangle.
                    triangles[i * triangleIndexSteps + 3] = i * vertexIndexSteps + 2;
                    triangles[i * triangleIndexSteps + 4] = i * vertexIndexSteps;
                    triangles[i * triangleIndexSteps + 5] = i * vertexIndexSteps + 3;

                    if (shouldBeDoubleSided)
                    {
                        //Third triangle.
                        triangles[i * triangleIndexSteps + 6] = i * vertexIndexSteps + 5;
                        triangles[i * triangleIndexSteps + 7] = i * vertexIndexSteps + 6;
                        triangles[i * triangleIndexSteps + 8] = i * vertexIndexSteps + 4;
                        //Forth triangle.
                        triangles[i * triangleIndexSteps + 9]  = i * vertexIndexSteps + 7;
                        triangles[i * triangleIndexSteps + 10] = i * vertexIndexSteps + 4;
                        triangles[i * triangleIndexSteps + 11] = i * vertexIndexSteps + 6;
                    }
                }
            }

            // TODO: Bubble sort with limited run time.
            finalMesh.vertices  = vertices;
            finalMesh.uv        = uvs;
            finalMesh.uv2       = uv2s;
            finalMesh.normals   = normals;
            finalMesh.tangents  = tangents;
            finalMesh.colors    = colors;
            finalMesh.triangles = triangles;
        }
        // MANAGE EVENT //
        //
        void ManageEvent(Vector4 input, bool isInputFloat, int particleIndex)
        {
            bool    shouldTriggerEvent = false;
            Vector4 rawProperty;
            bool    isRawPropertyFloat = isInputFloat;
            float   thePropertyValue   = 0;

            if (useCurrentStack.GetValue() == false)
            {
                rawProperty        = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)property.GetValue());
                isRawPropertyFloat = AmpsHelpers.isFloatInput((AmpsHelpers.eCurveInputs)property.GetValue());
            }
            else
            {
                rawProperty = input;
            }

            if (isRawPropertyFloat)
            {
                thePropertyValue = rawProperty.x;
            }
            else
            {
                switch (propertyVectorComponent.GetValue())
                {
                case (int)AmpsHelpers.eVectorComponents.X:
                    thePropertyValue = rawProperty.x;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Y:
                    thePropertyValue = rawProperty.y;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Z:
                    thePropertyValue = rawProperty.z;
                    break;

                case (int)AmpsHelpers.eVectorComponents.W:
                    thePropertyValue = rawProperty.w;
                    break;

                case (int)AmpsHelpers.eVectorComponents.Mag:
                    thePropertyValue = new Vector3(rawProperty.x, rawProperty.y, rawProperty.z).magnitude;
                    break;
                }
            }

            switch (condition.GetValue())
            {
            case (int)eConditions.Greater:
                shouldTriggerEvent = thePropertyValue > value.GetValue();
                break;

            case (int)eConditions.Less:
                shouldTriggerEvent = thePropertyValue < value.GetValue();
                break;

            case (int)eConditions.Equal:
                shouldTriggerEvent = thePropertyValue == value.GetValue();
                break;

            case (int)eConditions.NotEqual:
                shouldTriggerEvent = thePropertyValue != value.GetValue();
                break;
            }

            if (shouldTriggerEvent)
            {
                EventData theEventData = new EventData();
                theEventData.eventName     = eventName.GetValue();
                theEventData.particleIndex = particleIndex;
                theEventData.DataSlot1     = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)sentProperty1.GetValue());
                theEventData.DataSlot2     = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)sentProperty2.GetValue());
                theEventData.DataSlot3     = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)sentProperty3.GetValue());
                theEventData.DataSlot4     = AmpsHelpers.GetSystemProperty(ownerBlueprint, particleIndex, (AmpsHelpers.eCurveInputs)sentProperty4.GetValue());

                                #if UNITY_EDITOR
                AmpsEmitter[] selfAndChildEmitters = ownerBlueprint.ownerEmitter.transform.root.GetComponentsInChildren <AmpsEmitter>();
                for (int i = 0; i < selfAndChildEmitters.Length; i++)
                {
                    selfAndChildEmitters[i].AmpsHandleEvent(theEventData);
                }
                                #else
                ownerBlueprint.ownerEmitter.BroadcastMessage("AmpsHandleEvent", theEventData, SendMessageOptions.DontRequireReceiver);
                                #endif

                currentEventCount++;
                timeOfLastEvent = ownerBlueprint.ownerEmitter.emitterTime;
            }
        }
Example #11
0
        // INITIALIZE NEW PARTICLES //
        //
        override public void InitializeNewParticles()
        {
            // The base's code is duplicated bellow to save a funct call and a loop.
            // base.InitializeNewParticles();
            System.Random theRandom = new System.Random();

            if (theMesh == null)
            {
                return;
            }

            if (ownerBlueprint.ownerEmitter.newParticleIndices.Count > 0)
            {
                int elementCount = 0;
                if (sampledMeshElement.GetValue() == (int)eMeshElements.VertexNormal ||
                    sampledMeshElement.GetValue() == (int)eMeshElements.VertexPosition)
                {
                    elementCount = theMesh.vertices.Length;
                }
                else
                {
                    elementCount = theMesh.triangles.Length / 3;                        // Divide by 3 because its a list of vertex indices.
                }
                for (int i = 0; i < ownerBlueprint.ownerEmitter.newParticleIndices.Count; i++)
                {
                    int theParticleIndex = ownerBlueprint.ownerEmitter.newParticleIndices[i];

                    lastSampleTimes[theParticleIndex] = -1;
                    isValidSample[theParticleIndex]   = false;

                    if (theMesh != null)
                    {
                        switch ((eSamplingOrder)samplingOrder.GetValue())
                        {
                        case eSamplingOrder.Sequential:
                            elementIndices[theParticleIndex] = lastAssignedElementIndex;
                            lastAssignedElementIndex++;
                            if (lastAssignedElementIndex > elementCount - 1)
                            {
                                lastAssignedElementIndex = 0;
                            }
                            break;

                        case eSamplingOrder.Random:
                            elementIndices[theParticleIndex] = theRandom.Next(0, elementCount);
                            break;

                        case eSamplingOrder.IndexBased:
                            if (ownerBlueprint.ownerEmitter.particleIds.Length > elementCount)
                            {
                                elementIndices[theParticleIndex] = theParticleIndex % elementCount;
                            }
                            else
                            {
                                elementIndices[theParticleIndex] = theParticleIndex;
                            }
                            break;
                        }
                    }
                }
            }
        }
        // MANAGE SAMPLING //
        //
        // Does the actual sampling.
        override public void ManageSampling(int particleIndex)
        {
            int finalParticleIndex = (particleIndex < 0 ? 0 : particleIndex);

            AmpsHelpers.eCurveInputs wantedProperty = (AmpsHelpers.eCurveInputs)property.GetValue();
            bool isWantedPropertyParticleRelated    = AmpsHelpers.isParticleRelatedInput(wantedProperty);
            bool shouldIndeedSample = (particleIndex < 0 && ShouldSample()) || (particleIndex >= 0 && ShouldSample(particleIndex));

            if (wasParentChecked == false)
            {
                if (ownerBlueprint.ownerEmitter.transform.parent != null)
                {
                    parentEmitter = ownerBlueprint.ownerEmitter.transform.parent.GetComponent <AmpsEmitter>();
                }
                wasParentChecked = true;
            }

            if (sampleFromParent.GetValue())
            {
                // Leave if it's not time yet to sample.
                if (shouldIndeedSample == false)
                {
                    return;
                }

                // INVALID SAMPLE: Parent doesn't exist or has no emitter component or no blueprint.
                if (parentEmitter == null ||
                    parentEmitter.blueprint == null)
                {
                    isValidSample[finalParticleIndex] = false;
                    return;
                }

                // Try to get valid parent particle index.
                if (parentParticleIndices[finalParticleIndex] < 0)
                {
                    parentParticleIndices[finalParticleIndex] = parentEmitter.GetRandomParticleIndex(ownerBlueprint.ownerEmitter.particleIds[finalParticleIndex]);
                }

                // TODO: Invalid sample case: particle id at current particle index is different, ie we did lose
                // original particle index as it got replaced by another.

                // INVALID SAMPLE: Invalid parent particle index.
                //
                // TODO: We might have an invalid parent particle index but we might not need it anymore since
                // we already got a valid sample from it before and we don't need a new one for the time being.
                if (parentParticleIndices[finalParticleIndex] < 0)
                {
                    isValidSample[finalParticleIndex] = false;
                    return;
                }

                // INVALID SAMPLE: Parent particle is dead.
                if (parentParticleIndices[finalParticleIndex] >= 0 &&
                    parentEmitter.particleMarkers.IsActive(parentParticleIndices[finalParticleIndex]) == false)
                {
                    parentParticleIndices[finalParticleIndex] = -1;
                    isValidSample[finalParticleIndex]         = false;
                    return;
                }

                // INVALID SAMPLE: Asking for particle specific data but have no valid particle index.
                if (isWantedPropertyParticleRelated && parentParticleIndices[finalParticleIndex] < 0)
                {
                    return;
                }

                samples[finalParticleIndex] = AmpsHelpers.GetSystemProperty(parentEmitter.blueprint,
                                                                            parentParticleIndices[finalParticleIndex],
                                                                            wantedProperty);
                isValidSample[finalParticleIndex] = true;
            }
            else
            {
                // Leave if it's not time yet to sample.
                if (shouldIndeedSample == false)
                {
                    return;
                }

                // INVALID SAMPLE: Asking for particle specific data but have no valid particle index.
                if (isWantedPropertyParticleRelated && finalParticleIndex < 0)
                {
                    return;
                }

                samples[finalParticleIndex] = AmpsHelpers.GetSystemProperty(ownerBlueprint,
                                                                            finalParticleIndex,
                                                                            wantedProperty);
                isValidSample[finalParticleIndex] = true;
            }
        }