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

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值