63粒子系统

西昌.何雨锋  粒子系统

ravity(重力)  bounce反弹   generator(创始人)    blend(混合)
[setSetEmittorMoveMode(常量);    CONST_TV_EMITTORMOVEMODE 常量为:  TV_EMITTOR_LERP = 0   TV_EMITTOR_NOLERP = 1
设置辐射移动模式:有/无]
[SetNewParticleData(发散x,发散y,发散z,颜色R,颜色B,颜色C,生命周期,纹理图)
 用于实时改变粒子系统的参数],这里的函数VScale,VNormalize都是global的函数
V = gloabal1->VScale(global1->VNormalize(&Vector(Rnd * 2 - 1, Rnd * 4 + 2, Rnd * 2 - 1)), CurrentPower)
[
par1->UpdateParticles(常量CONST_TV_PARTICLEUPDATE)
常量CONST_TV_PARTICLEUPDATE: 
TV_UPDATE_ACTIVE = 0  Update only active particles 
TV_UPDATE_NON_ACTIVE = 1  Update only non-active particles 
TV_UPDATE_BOTH = 2  Updates non-active and active particle. 
TV_UPDATE_GENERATOR = 4  Generates new particle when needed. 
TV_UPDATE_RANDOM_GENERATOR = 8  随机起点. 
TV_UPDATE_FOLLOW_LANDSCAPE = 16  Particles must follow the terrain (altitude) 
TV_UPDATE_BOUNCE_ON_LANDSCAPE = 32  在陆地高度将反弹

TV_UPDATE_BOUNCE_ON_Y0_PLANE = 64  在Y=0的零高度将反弹 
TV_UPDATE_BOUNCE_ON_CUSTOM_PLANE = 128  particles Must bounce on a custom defined plane 
]

ITVParticleSystem par1;
par1=CreateTVParticleSystem();
par1->CreateBillboardSystem(1000,0,5,&pos1,3000,global1->GetTex("water1"));
//pos1是D3DVECTOR,在读取粒子图的时候,记得用参数TV_COLORKEY_BLACK,这样读出的粒子图才不是方的。
    par1->SetGravity(3,0.5);   //设置重力和反弹强度
    par1->SetGeneratorSpeed(10);  //设置初始速度
    par1->ParticleSize=3;         //设置粒子大小
//以上三项是可以直接调整的。

//记得渲染
    par1->UpdateParticles(TV_UPDATE_BOUNCE_ON_LANDSCAPE);
    par1->RenderParticles();
 
//end
以下问题是没搞懂的:1、在很多par1的set函数中有long particle的参数,不知道从哪个类里能得到这个,所以很多set函数根本用不起。
                    2、如何让par1分开和有方向。
以下问题基本清楚:
    1、par1->UpdateParticles(TV_UPDATE_BOUNCE_ON_LANDSCAPE);
是用来说明当粒子碰到land时会反弹,如果改成FLOOR参数则碰到地板会反弹。
    2、par1->CreateBillboardSystem(粒子数量,起数,结束数,&Vector,范围?,long型的图片)
    3、可以用puase与stop函数控制其是否暂停。
    4、可以用moveEmittor(&pos)将其移动到另一个地方。
    5、可以用SetParticleTexture(纹理)来改变纹理。
    6、GetActiveParticlesNumber()好象是返回粒子的总浈数,然后可以用循环得到 某一贞,然后就可以用那些set来设置每一贞所体现不同的效果了?
创建粒子有很多种方法:
一、最简单的方法:只定义粒子本身,然后用自动生成功能产生简单的粒子。
    par1->CreateBillboardSystem(153,0,3,&par_pos,0,global1->GetTex("par1"));
    par1->SetAlphaBlendingMode(TV_CHANGE_ALPHA,(TrueVision3D::CONST_D3DBLEND) D3DBLEND_SRCALPHA,(TrueVision3D::CONST_D3DBLEND) D3DBLEND_ONE);
    par1->SetParticleAutoGenerateMode(tvtrue,0.4,0.4,0.4,0.4,0.8,0,0.1,0,0.01,0.01,0.01);
    par1->ParticleSize=28;     //大小   
    par1->SetGeneratorSpeed(21);  //粒子产生速度
    par1->SetParticleSpeed(0.2);  //粒子运动速度*/
    这样产生的粒子可以控制简单的分岔功能,但是无法控制粒子飞出的方向和飞行轨迹。
二、使用轨迹系统来编辑粒子的轨迹:
    D3DVECTOR tmpVel;
    tmpVel.x = rand()* 2 - 1;
    tmpVel.y = rand()* 4 + 2;
    tmpVel.z = rand()* 2 - 1;
    tmpVel =global1->VScale(global1->VNormalize(&tmpVel),1.4);
    par1->MoveEmittor(&Pos1);               //这个是控制整个粒子产生器的位置的,一般随着物体运动
    par1->SetParticleAutoGenerateMode(tvtrue,0.4,0.4,0.4,0.4,0.8,tmpVel.x,tmpVel.y,tmpVel.z,0.01,0.01,0.01);  //这里是控制粒子产生器产生出粒子的形状的
    这样编辑出的粒子不但可以控制轨迹(由pos1控制),而且可以控制粒子群的变化和形状(由tempvel控制)。
    par1->SetParticleAutoGenerateMode(enable,红,绿,蓝,A,粒子生命周期,粒子微器的x,粒子微器的y,粒子微器的z,随机因子x,随机因子y,随机因子z);
    注意,这部分将被加到循环中,这样才能产生出烟花般的粒子系统,其中粒子微器坐标可以自己用公式计算,也可以使用TV自带的
    粒子编辑器中的运算代码,然后通过此代码算出粒子微器坐标,这样就产生了同粒子编辑器相同的粒子群了。

三、使用两个点:位置点与方向点,可以控制出有方向的粒子系统。
    myPos = new DxVBLibA::D3DVECTOR;
    myPos->x = 1;
    myPos->z = 1;
    myPos->y = 1;
    myDir = new DxVBLibA::D3DVECTOR;
    myDir->x = 1;
    myDir->z = 1;
    myDir->y = 1;
    myParticleSystem->CreateBillboardSystem(1000, 1, 3.0, myPos, 3.0, pGlobals->GetTex("ParticleTexture"));
    myParticleSystem->CreateSystemFromPreset(TV_PARTICLE_EXPLOSIONUP, 1000, myPos, myDir, pGlobals->GetTex("ParticleTexture"), -1);
    render中://这里忽略了编辑粒子轨迹的过程
    myParticleSystem->UpdateParticles(TV_UPDATE_BOTH);
    myParticleSystem->RenderPreset();

----------------------------------------我
用0键来实现了一键让粒子到或出现在某个方向
if(input1->IsKeyPressed(TV_KEY_0))
    {
       int kk;
    int i,j;
    kk=par1->GetActiveParticlesNumber();
    for(i=1;i<=kk-1;i++)
    {
     j=par1->GetParticleKey(i);
     par1->SetParticlePosition(&posb,i);
                   par1->SetParticleDirection(&posb,i);
    }

--------------------------------------------------------------------------------
粒子的代码:外
With My_Particle1
       .CreateBillboardSystem 543, 0, 3, Vector3(0,0,0), 0, GetTex("My_Texture1")
       .ParticleSize = 14
       .SetAlphaBlendingMode TV_CHANGE_ALPHA, D3DBLEND_SRCALPHA, D3DBLEND_ONE
       .SetGravity 2, .4
       .SetGeneratorSpeed 7
       .SetParticleSpeed .01
End With

'Event Code for My_Particle1 :
    LifeTime = 3.1
    Dim tmpVel as D3DVECTOR
    tmpVel.x = Rnd * 2 - 1
    tmpVel.y = Rnd * 4 + 2
    tmpVel.z = Rnd * 2 - 1
    tmpVel = VScale(VNormalize(tmpVel), 1.4)
    VelocX = tmpVel.x
    VelocY = tmpVel.y
    VelocZ = tmpVel.z
    Dim tmpPos As Integer
    Dim vNewPosition As D3DVECTOR
    tmpPos = (TV.TickCount * .52) Mod 360
    vNewPosition.x = Sin(Deg2Rad(tmpPos)) * 0 + 0
    vNewPosition.y = Sin(Deg2Rad(tmpPos)) * 1 + 0
    vNewPosition.z = Cos(Deg2Rad(tmpPos)) * 0 + 0
    My_Particle1.MoveEmittor vNewPosition
    ColorR = 1.568628E-02
    ColorG = .2509804
    ColorB = .7176471
    ColorA = 1

    My_Particle1.UpdateParticles TV_UPDATE_BOUNCE_ON_Y0_PLANE Or TV_UPDATE_GENERATOR
    My_Particle1.RenderParticles
--------------------------

/********************************************************
* Copyright (C) Truevision3D LLC.                  *
* File:         Tutorial 1.cpp                     *
* Description:   TrueVision3D Tutorial 1               *
* Written By:   MadProgrammer                     *
********************************************************/

#include "stdafx.h"
#include "../tv3dcpp.h"

 

//Setup TrueVision3D
ITVEngine pEngine;
ITVInputEngine pInput;
ITVScene pScene;
ITVMesh myMesh;
ITVGlobals pGlobals;

ITVParticleSystem myParticleSystem;

 

void render();
void input();
void unload();

DxVBLibA::D3DVECTOR* myPos;
DxVBLibA::D3DVECTOR* myDir;

LRESULT CALLBACK WndProc(HWND wpHWnd, UINT msg, WPARAM wParam, LPARAM lParam);

float fAngle = 0;
float fTimeElapsed = 0;

//WinMain: The entry point to everything Windows
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   HWND WindowHandle;
//   HINSTANCE hInst;
   
   WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "MyParticles", NULL };
    RegisterClassEx(&wc);

   WindowHandle = CreateWindow( "MyParticles", "Small System",
                              WS_OVERLAPPEDWINDOW, 100, 100, 640, 480,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

   // there is a problem creating the window
   if (WindowHandle ==  NULL)
   {
      MessageBox(NULL, "Unable to Create a Window", "Error", MB_OK);
      return false;
   }


    ShowWindow      (WindowHandle, 1);
    UpdateWindow   (WindowHandle);
    SetFocus      (WindowHandle);
    ShowCursor      (TRUE);

   //Initialze COM
   CoInitialize(NULL);

   pEngine = CreateTVEngine();
   
   //Engine Running boolean
   double Gamma = 0.0;
   MSG msg;
   msg.message = WM_NULL;

   //Set the debug file before doing anything else
   pEngine->SetDebugFile ("c://debug.txt");
   
   //Initialize Windowed
   pEngine->Init3DWindowedMode ((long)WindowHandle, true);

   //Tell it to display the FPS
   pEngine->put_DisplayFPS(tvtrue);

   //Init input after main init
   pInput = CreateTVInputEngine();   

   //AppPath is a small Macro function in tv3dcpp lib to return the path
   //of a file you pass to it, in this case we get the application path
   char path[256];
   char srchpath[256];
   
   HMODULE Module = (HMODULE)hInstance;
   GetModuleFileName(Module,path,255);

   AppPath(path,srchpath);   
   
   //Set the search directory of the objects, textures, ...
   pEngine->SetSearchDirectory(srchpath);

   //We set the AngleSystem to Degrees
   pEngine->SetAngleSystem (TV_ANGLE_DEGREE);

   //Init input after main init, and check if it errors anywhere.
   pInput = CreateTVInputEngine();
   pScene = CreateTVScene();   
   pGlobals = CreateTVGlobals();      

    
    long LoadTexRet;
   LoadTexRet=pScene->LoadTexture ("..//..//..//Media//texture.bmp", -1, -1, "ParticleTexture");
   if(LoadTexRet==0)
      MessageBox(NULL, "The Texture did not load properly", "Error", MB_OK);

   // Create System
   
   myPos = new DxVBLibA::D3DVECTOR;
   myPos->x = 1;
   myPos->z = 1;
   myPos->y = 1;

   myDir = new DxVBLibA::D3DVECTOR;
   myDir->x = 1;
   myDir->z = 1;
   myDir->y = 1;

   myParticleSystem->CreateBillboardSystem(1000, 1, 3.0, myPos, 3.0, pGlobals->GetTex("ParticleTexture"));
   myParticleSystem->CreateSystemFromPreset(TV_PARTICLE_EXPLOSIONUP, 1000, myPos, myDir, pGlobals->GetTex("ParticleTexture"), -1);
                                 

   /* CreateSystemFromPreset( Preset As CONST_TV_PARTICLE_PRESET, NumParticles As Integer,
                     Position As D3DVECTOR, Direction As D3DVECTOR, Texture As Long, Color As Long)
 */

   /* TVParticleSystem.CreateBillboardSystem( ParticleCount As Integer, ParticleStart As Integer,
                     SquareSize As Single, Position As D3DVECTOR, Radius As Single, Texture As Long)
*/

   
   //Main loop   
   while( msg.message!=WM_QUIT)
   {
      if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
      {
         TranslateMessage( &msg );
         DispatchMessage( &msg );
      }
      else
      {      
         render();
         input();
      }
   }      

   //Uninitialize the variables
   pInput->Release ();
   pInput = NULL;

   pEngine->Release ();
   pEngine = NULL;
   
   //Uninitialize COM
   CoUninitialize();

   //Exit sucessfully
   return 0;
}

//Render sub
void render()
{
   pEngine->Clear(false);                  //Clear the screen

   //myParticleSystem->UpdateParticles(TV_UPDATE_BOTH);
   //myParticleSystem->RenderParticles();
   myParticleSystem->UpdateParticles(TV_UPDATE_BOTH);
   myParticleSystem->RenderPreset();

   pEngine->RenderToScreen ();               //Render the screen   

}

//Input sub
void input()
{
   if(pInput->IsKeyPressed(TV_KEY_ESCAPE))      //Check if ESCAPE has been pressed.
   {      
      PostQuitMessage(0);
   }
}

LRESULT CALLBACK WndProc(HWND wpHWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

   switch(msg)
   {   
      case WM_DESTROY:
      {
         PostQuitMessage(0);
         return 0;
      } break;


      default:break;
   }


   return DefWindowProc(wpHWnd, msg, wParam, lParam);

}


-------------------------------------外
下面的是使用long的粒子来更改每一贞。
Private Sub Particle_Do()

        facex = Math.Sin(Facing)
        facez = Math.Cos(Facing)

        particlenumber = particle.GetActiveParticlesNumber()
        Dim i As Integer

        For i = 0 To particlenumber-1
            key = particle.GetParticleKey(i)
            vector.x = ship.GetPosition.x - (180 * facex * (key + 0.1))
            vector.z = ship.GetPosition.z - (180 * facez * (key + 0.1))
            vector.y = -3
            particle.SetParticlePosition(vector, i)
        Next i

        particle.UpdateParticles()
        particle.RenderParticles()

    End Sub

---------------------------------------外
下面是C#的让粒子随路径行动的例子

Particle follow Path

First we need a Path:

PPath := TTVPath.Create(nil);
PPath.SetPathType(TV_PATH_LINEAR);

We add some Nodes:

PPath.AddNode(100,1000,100);
PPath.AddNode(2500,500,2500);
PPath.AddNode(0,100,2500);
PPath.AddNode(500,1000,3000);
PPath.AddNode(2500,100,3500);
PPath.AddNode(3500,2000,4000);
PPath.AddNode(3500,100,900);
PPath.AddNode(5000,1500,0);


Then we need a Particle System:

FParti := TTVParticleSystem.Create(NIL);
FParti.OnNewParticle := NewParticle; // OnNewParticle Event &#133; see SDK

And :

type
TRelPos = Record
RelX : Single;
RelY : Single;
RelZ : Single;
Posi : Single;
end;

RelPos : Array of TRelPos; //Dynamic Array

 

The Event :

FParti .NewParticle(ASender : TObject; Var VelocX, VelocY, VelocZ, ColorR, ColorG,
ColorB, ColorA, LifeTime: Single; Var TextureIndex : Integer);
Begin

TextureIndex := Global. GetTex(&#145;particletexture&#146;)
ColorR := 1;
ColorG := 1;
ColorB := 1;
ColorA := 1;
LifeTime := 30;

// VelocX .. Z is not needed because we move our Particles &#145;manually&#146;
End ;


Now we need a Startup Procedure for the Random Positions of the Particles.

Procedure StartUp;
Var I : Integer;
Begin
Randomize;
SetLength(RelPos, ParticleCount); //wahtever your count is ..
for i := 0 to length(RelPos)-1 do
begin
RelPos[i].RelX := RandomRange(100, -100); // so you have a cube where the Particles be &#145;borne&#146; 
RelPos[i].RelY := RandomRange(100, -100);
RelPos[i].RelZ := RandomRange(100, -100);
RelPos[i].Posi := 1; // its the first Node &#133; if you set 0 the Particle Starts at the last Node .. test it 
end;
End;


The Follow Path Procedure called in the render Loop:

procedure TParticles.follow;
var i : Integer; RandPos : _D3DVECTOR;
begin
for i := 0 to ParticleCount do
begin
RandPos.x := PPath.GetSplinePoint(RelPos[i].Posi).x + RelPos[i].RelX; // now we get the Position of a SplinePoint on the Path
RandPos.y := PPath.GetSplinePoint(RelPos[i].Posi).y + RelPos[i].RelY; // and add the relative Positions
RandPos.z := PPath.GetSplinePoint(RelPos[i].Posi).z + RelPos[i].RelZ;
FParti.SetParticlePosition(RandPos, i+1); // Set The Position of each Particle.
RelPos[i].Posi := RelPos[i].Posi + 0.01; // 0.01 means the Speed if you set to 1 .. it&#146;s the next Node
if RelPos[i].Posi >= PPath.GetNodeCount then RelPos[i].Posi := 1; // if the last Node reached .. we start at 1
end;
end;


You should set the LifeTime > 0, the EmmetorSpeed := 50 (play wit it ) )
---------------------------------------------------外
看来那个long particle只是一个粒子了

for ParticleIndex= 1 to 32000
     ParticleEngine.SetParticlePosition (vector3(Xpos, Ypos, Zpos), ParticleIndex)
     ParticleEngine.SetParticleLifeTime(lifetime, ParticleIndex)
     ParticleEngine.SetParticleDirection(Vector3(Xdir, Ydir, Zdir), ParticleIndex)
     ParticleEngine.SetParticleColor(red, geewn, blue, alpha, ParticleIndex)
next ParticleIndex

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值