Beispiel #1
0
        /// <summary>
        /// emits the specified particle object according to the emit type.
        /// </summary>
        /// <param name="obj">a particle object</param>
        protected void EmitParticle(ref ParticleObject obj)
        {
            float massRange = 0.0f;
            Matrix mtx1 = Matrix.Identity;
            float rnd1 = 0.0f, rnd2 = 0.0f;

            obj.state = (uint)(ParticleObject.States.Enable | 
                               ParticleObject.States.Fired | 
                               ParticleObject.States.FirstTime);

            obj.time = 0.0f;
            obj.posInterval = Info.PositionUpdateInterval;
            obj.scaleInterval = Info.ScaleUpdateInterval;
            obj.textureSequenceInterval = 0.0f;

            massRange = Info.MassMax - Info.MassMin;
            obj.mass = Info.MassMin + (HelperMath.RandomNormal() * massRange);
            obj.gravity = Vector3.Zero;
            obj.posRandomInterval = Info.PositionRandomInterval;

            switch (Info.EmitType)
            {
                //  CONE type : changes tje direction randomly 
                //  from the default EmitDirection.
                case ParticleInfo.EmitObjectType.Cone:
                    {
                        rnd1 = HelperMath.RandomNormal2() * Info.EmitAngle;
                        rnd2 = HelperMath.RandomNormal2() * Info.EmitAngle;

                        mtx1 = Matrix.CreateFromAxisAngle(emitRight, 
                                                          MathHelper.ToRadians(rnd1));

                        mtx1 = mtx1 * Matrix.CreateFromAxisAngle(emitUp, 
                                                          MathHelper.ToRadians(rnd2));

                        obj.emitDir = Vector3.TransformNormal(Info.EmitDirection, mtx1);

                        obj.startPos = Info.EmitPosition;
                    }
                    break;
                //  SPHERE type : make the emit direction to the total random direction.
                case ParticleInfo.EmitObjectType.Sphere:
                    {
                        obj.emitDir = HelperMath.RandomVector2();
                        obj.emitDir.Normalize();
                        obj.startPos = Info.EmitPosition;
                    }
                    break;
                //  Disk type: basically same as the cone,
                //  (however, except the rotation around the EmitUpVector as the axis)
                //  it makes the direction which is randomly turned 
                //  as the UpVector as the axis. 
                case ParticleInfo.EmitObjectType.Disk:
                    {
                        rnd1 = HelperMath.RandomNormal2() * Info.EmitAngle;

                        mtx1 = Matrix.CreateFromAxisAngle(emitRight, 
                                                          MathHelper.ToRadians(rnd1));

                        mtx1 = mtx1 * Matrix.CreateFromAxisAngle(Info.UpVector, 
                                                        HelperMath.RandomNormal() *
                                                        2.0f *
                                                        MathHelper.Pi);

                        obj.emitDir = Vector3.TransformNormal(Info.EmitDirection, mtx1);

                        obj.startPos = Info.EmitPosition;
                    }
                    break;
                //  RECT_PLANE type : The EmitAngle will follow the size 
                //  of a square area, not an angle.
                //  The EmitDirection is always constant.
                case ParticleInfo.EmitObjectType.RectPlane:
                    {
                        obj.emitDir = Info.EmitDirection;

                        rnd1 = (HelperMath.RandomNormal2() * 0.5f) * Info.EmitAngle;
                        rnd2 = (HelperMath.RandomNormal2() * 0.5f) * Info.EmitAngle;
                        obj.pos[0] = upRight * rnd1;
                        obj.pos[0] += upAt * rnd2;

                        obj.startPos = obj.pos[0] + Info.EmitPosition;
                    }
                    break;
                //  CIRCLE_PLANE type : The circular area whose radius is the EmitAngle.
                case ParticleInfo.EmitObjectType.CirclePlane:
                    {
                        obj.emitDir = Info.EmitDirection;

                        rnd1 = HelperMath.RandomNormal() * Info.EmitAngle;
                        rnd2 = HelperMath.RandomNormal() * MathHelper.Pi * 2.0f;

                        obj.pos[0] = upRight * rnd1;  //  Scaling

                        mtx1 = Matrix.CreateFromAxisAngle(Info.UpVector, rnd2);

                        obj.pos[0] = Helper3D.TransformCoord(obj.pos[0], mtx1);
                        obj.startPos = obj.pos[0] + Info.EmitPosition;
                    }
                    break;
            }

            if (refEnable)
            {
                obj.startPos = Helper3D.TransformCoord(obj.startPos, (Matrix)refMatrix);
                obj.emitDir = Vector3.TransformNormal(obj.emitDir, (Matrix)refMatrix);
            }

            obj.pos[0] = obj.startPos;
            obj.scale = Vector3.Zero;

            obj.posRandom = 1.0f + ((HelperMath.RandomNormal2() * 0.5f) * 
                                    Info.PositionInitialRandomFactor);

            obj.scaleRandom = 1.0f + ((HelperMath.RandomNormal2() * 0.5f) * 
                                        Info.ScaleInitialRandomFactor);

            obj.rotateRandom = HelperMath.RandomNormal2();

            switch (Info.ParticleType)
            {
                case ParticleInfo.ParticleObjectType.AnchorBillboard:
                    {
                        obj.pos[1] = obj.pos[0];
                    }
                    break;
                case ParticleInfo.ParticleObjectType.Scene:
                    {
                        obj.rotateDir = HelperMath.RandomVector2();
                    }
                    break;
            }

            {
                for (int i = 0; i < posArgCount; i++)
                    obj.posArg[i] = Info.PositionInit[i];

                for (int i = 0; i < scaleArgCount; i++)
                    obj.scaleArg[i] = Info.ScaleInit[i];

                obj.rotateAccm = Info.RotateInit + (HelperMath.RandomNormal2() * 
                                                    Info.RotateRandomFactor);
            }
        }
Beispiel #2
0
        /// <summary>
        /// by using the particle information, a particle object is created
        /// and initialized.
        /// </summary>
        public void Create()
        {
            //  Initialize Particle Information 
            Info.Initialize();

            Name = sequenceInfo.Name;
            sceneRoot.RemoveAllChild(false);

            if (sequenceInfo.TextureFileName.Length > 0)
            {
                string resourceFullPath = 
                            Path.Combine(resourcePath, sequenceInfo.TextureFileName);

                GameResourceTexture2D resource = 
                            FrameworkCore.ResourceManager.LoadTexture(resourceFullPath);
                
                //  Set to texture
                Texture = resource.Texture2D;

                //  Set to texture in TextureSequence 
                if (TextureSequence != null)
                    TextureSequence.SetTexture(Texture);
            }

            enableRotate = false;

            switch (Info.ParticleType)
            {
                    //  PointSprite
                case ParticleInfo.ParticleObjectType.PointSprite:
                    {
                        scenePointSprite = new GamePointSprite();
                        scenePointSprite.Create(Info.MaxObjectCount, Texture, 
                                                RenderingSpace.World, false);

                        scenePointSprite.AlphaBlendEnable = 
                            sequenceInfo.AlphaBlendEnable;
                        scenePointSprite.DepthBufferEnable = 
                            sequenceInfo.DepthBufferEnable;
                        scenePointSprite.SourceBlend = 
                            sequenceInfo.SourceBlend;
                        scenePointSprite.DestinationBlend = 
                            sequenceInfo.DestinationBlend;
                        scenePointSprite.BlendFunction = 
                            sequenceInfo.BlendFunction;
                        scenePointSprite.DepthBufferEnable = true;
                        scenePointSprite.DepthBufferWriteEnable = false;
                        scenePointSprite.DepthBufferFunction = CompareFunction.Less;
                        scenePointSprite.AlphaFunction = CompareFunction.Greater;
                        scenePointSprite.CullMode = CullMode.None;

                        sceneRoot.AddChild(scenePointSprite);
                    }
                    break;
                    //  Sprite3D
                case ParticleInfo.ParticleObjectType.Sprite:
                    {
                        sceneSprite3D = new GameSprite3D();
                        sceneSprite3D.Create(Info.MaxObjectCount, Texture, 
                                             RenderingSpace.World, false);

                        sceneSprite3D.AlphaBlendEnable = 
                            sequenceInfo.AlphaBlendEnable;
                        sceneSprite3D.DepthBufferEnable = 
                            sequenceInfo.DepthBufferEnable;
                        sceneSprite3D.SourceBlend = 
                            sequenceInfo.SourceBlend;
                        sceneSprite3D.DestinationBlend = 
                            sequenceInfo.DestinationBlend;
                        sceneSprite3D.BlendFunction =
                            sequenceInfo.BlendFunction;
                        sceneSprite3D.DepthBufferEnable = true;
                        sceneSprite3D.DepthBufferWriteEnable = false;
                        sceneSprite3D.DepthBufferFunction = CompareFunction.Less;
                        sceneSprite3D.AlphaFunction = CompareFunction.Greater;
                        sceneSprite3D.CullMode = CullMode.None;

                        sceneRoot.AddChild(sceneSprite3D);

                        enableRotate = true; //  Possible to rotation
                    }
                    break;
                    //  Billboard
                case ParticleInfo.ParticleObjectType.AnchorBillboard:
                case ParticleInfo.ParticleObjectType.Billboard:
                    {
                        sceneBillboard = new GameBillboard();
                        sceneBillboard.Create(Info.MaxObjectCount, Texture, 
                                              RenderingSpace.World, false);

                        sceneBillboard.AlphaBlendEnable = 
                            sequenceInfo.AlphaBlendEnable;
                        sceneBillboard.DepthBufferEnable = 
                            sequenceInfo.DepthBufferEnable;
                        sceneBillboard.SourceBlend = 
                            sequenceInfo.SourceBlend;
                        sceneBillboard.DestinationBlend =
                            sequenceInfo.DestinationBlend;
                        sceneBillboard.BlendFunction = 
                            sequenceInfo.BlendFunction;
                        sceneBillboard.DepthBufferEnable = true;
                        sceneBillboard.DepthBufferWriteEnable = false;
                        sceneBillboard.DepthBufferFunction = CompareFunction.Less;
                        sceneBillboard.AlphaFunction = CompareFunction.Greater;
                        sceneBillboard.CullMode = CullMode.None;

                        sceneRoot.AddChild(sceneBillboard);
                    }
                    break;
                    //  Mesh
                case ParticleInfo.ParticleObjectType.Scene:
                    {
                        if( Info.MeshData != null)
                        {
                            int vertextCount = Info.MeshData.Position.Count;
                            int indexCount = 0;

                            if (Info.MeshData.Index != null)
                                indexCount = Info.MeshData.Index.Count;

                            sceneMesh = new GameMesh();
                            sceneMesh.Create(vertextCount, indexCount, Texture);

                            sceneMesh.AlphaBlendEnable = 
                                sequenceInfo.AlphaBlendEnable;
                            sceneMesh.DepthBufferEnable = 
                                sequenceInfo.DepthBufferEnable;
                            sceneMesh.SourceBlend =
                                sequenceInfo.SourceBlend;
                            sceneMesh.DestinationBlend = 
                                sequenceInfo.DestinationBlend;
                            sceneMesh.BlendFunction =
                                sequenceInfo.BlendFunction;
                            sceneMesh.DepthBufferEnable = true;
                            sceneMesh.DepthBufferWriteEnable = false;
                            sceneMesh.DepthBufferFunction = CompareFunction.Less;
                            sceneMesh.AlphaFunction = CompareFunction.Greater;
                            sceneMesh.CullMode = CullMode.None;

                            //  Has position data
                            if (Info.MeshData.HasPosition )
                            {
                                sceneMesh.SetPositionData(
                                                Info.MeshData.Position.ToArray());
                            }

                            //  Has color data
                            if (Info.MeshData.HasColor )
                            {
                                sceneMesh.SetColorData(
                                                Info.MeshData.Color.ToArray());
                            }

                            //  Has texture coordinate data
                            if (Info.MeshData.HasTextureCoord )
                            {
                                sceneMesh.SetTextureCoordData(
                                                Info.MeshData.TextureCoord.ToArray());
                            }

                            //  Has index data
                            if (Info.MeshData.HasIndex )
                            {
                                sceneMesh.SetIndexData(Info.MeshData.Index.ToArray());
                            }

                            //  Use VB and IB
                            if (sceneMesh.userPrimitive == false)
                            {
                                sceneMesh.BindVertexBuffer();
                                sceneMesh.BindIndexBuffer();
                            }

                            sceneRoot.AddChild(sceneMesh);
                        }

                        enableRotate = true; //  can rotate
                    }
                    break;
            }

            SetSceneEnable(false);

            //  Particle Object
            particleObjectList.Clear();
            for (int i = 0; i < Info.MaxObjectCount; i++)
            {
                ParticleObject obj = new ParticleObject();
                particleObjectList.Add(obj);
            }

            // Emit Right & Up Vector
            {
                Matrix mtx = Helper3D.MakeMatrixWithAt(Info.EmitDirection, 
                                                       Info.UpVector);

                emitRight = mtx.Right;
                emitUp = mtx.Up;
            }

            // Up Right & At Vector
            {
                Matrix mtx = Helper3D.MakeMatrixWithUp(Info.UpVector, 
                                                       Matrix.Identity.Forward);

                upRight = mtx.Right;
                upAt = mtx.Forward;
            }

            posArgCount = 0;
            for (int i = ParticleInfo.FuncCount - 1; i >= 0; i--)
            {
                if (Info.PositionFunc[i] != ParticleInfo.FuncType.None)
                {
                    posArgCount = i + 1;
                    break;
                }
            }

            scaleArgCount = 0;
            for (int i = ParticleInfo.FuncCount - 1; i >= 0; i--)
            {
                if (Info.ScaleFunc[i] != ParticleInfo.FuncType.None)
                {
                    scaleArgCount = i + 1;
                    break;
                }
            }

            if( Info.IsPositionStyle( ParticleInfo.ParamStyles.Interpolate))
                positionInterpolate = KeyFrameTable.Interpolation.Lerp;
            else
                positionInterpolate = KeyFrameTable.Interpolation.None;

            if (Info.IsScaleStyle(ParticleInfo.ParamStyles.Interpolate))
                scaleInterpolate = KeyFrameTable.Interpolation.Lerp;
            else
                scaleInterpolate = KeyFrameTable.Interpolation.None;

            if (Info.IsColorStyle(ParticleInfo.ParamStyles.Interpolate))
                colorInterpolate = KeyFrameTable.Interpolation.Lerp;
            else
                colorInterpolate = KeyFrameTable.Interpolation.None;

            rObjectLifeTime = 1.0f / Info.ObjectLifeTime;

            isStarting = false;
            isStopping = false;
        }