Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

unit app_particle_part;

interface

uses sux_constant, sux_object, app_constant, resource_texture,
     resource_list, app_particle_vertexbuffer;

type
  TSAnimation = record
    addpos: SXVertex2D;
    addrot: SXFloat;
    addsize: SXFloat;
    addcolor: SXColorRGB;
    adddensity: SXFloat;
    movealongrot: SXVertex2D;
  end;
  TSettings = record
    typus: SXState;
    pos: SXVertex2D;
    rot: SXFloat;
    size: SXFloat;
    color: SXColorRGB;
    density: SXFloat;
    animation: TSAnimation;
    lifetime: SXFloat;
  end;
  SAPPart=class(SUXObject)
    settings: TSettings;

    procedure onRender(const vertexbuffer: SAPVertexBuffer; const particleindex: SXInt); overload; virtual;
    procedure onRender; overload; virtual;

    procedure setTypus(const typus: SXState);
    procedure setPosition(const pos: SXVertex2D);
    procedure setRotation(const rot: SXFloat);
    procedure setSize(const size: SXFloat);
    procedure setColor(const color: SXColorRGB);
    procedure setDensity(const density: SXFloat);
    procedure setAnimation(const addpos: SXVertex2D; const addrot, addsize: SXFloat; const addcolor: SXColorRGB; const adddensity: SXFloat);
    procedure setAnimationMoveAlongRot(const movealongrot: SXVertex2D);
    function getTypus: SXState;
    function getPosition: SXVertex2D;
    function getRotation: SXFloat;
    function getSize: SXFloat;
    function getColor: SXColorRGB;
    function getDensity: SXFloat;

    function getVectorFromRotation: SXVertex2D;
    procedure processAnimation;
    procedure deleteIfInvisible;
    procedure onTimer; virtual;

    procedure delete;
    constructor Create(const parent: TObject);
    destructor Destroy; override;
  end;

implementation

uses main, gl_main, OpenGL, app_particle_main, Math;


// --- SAPPart


procedure SAPPart.onRender(const vertexbuffer: SAPVertexBuffer; const particleindex: SXInt);
var vertexindex: SXInt;
    upvector: SXVertex2D;
    pos3D, upvectorandsize: SXVertex3D;
    color: SXColorRGBA;
    angle: SXFloat;
begin
  vertexindex := particleindex * 4;

  angle := (settings.rot);
  angle := degtorad(angle);
  upvector := sx.convert.Vertex2DOf(sin(angle), cos(angle));

  pos3D := sx.convert.Vertex3DOf(settings.pos.x, settings.pos.y, 0);
  upvectorandsize := sx.convert.Vertex3DOf(upvector.x, upvector.y, settings.size);
  color := sx.convert.ColorRGBAOf(settings.color.r, settings.color.g, settings.color.b, settings.density);

  vertexbuffer.setVertex(vertexindex, pos3D, color,
    sx.convert.Vertex2DOf(0, 0),
    sx.convert.Vertex2DOf(-1, -1), upvectorandsize);

  vertexbuffer.setVertex(vertexindex + 1, pos3D, color,
    sx.convert.Vertex2DOf(1, 0),
    sx.convert.Vertex2DOf( 1, -1), upvectorandsize);

  vertexbuffer.setVertex(vertexindex + 2, pos3D, color,
    sx.convert.Vertex2DOf(1, 1),
    sx.convert.Vertex2DOf( 1,  1), upvectorandsize);

  vertexbuffer.setVertex(vertexindex + 3, pos3D, color,
    sx.convert.Vertex2DOf(0, 1),
    sx.convert.Vertex2DOf(-1,  1), upvectorandsize);
end;


procedure SAPPart.onRender;
begin
  // Default rendering method
  glPushMatrix;

  glTranslatef(settings.pos.x,settings.pos.y,0);
  glRotatef(360 - settings.rot,0,0,1);
  glScalef(settings.size,settings.size,1);

  glColor4f(settings.color.r, settings.color.g, settings.color.b, settings.density);
  glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex2f(-1,-1);
    glTexCoord2f(1,0); glVertex2f( 1,-1);
    glTexCoord2f(1,1); glVertex2f( 1, 1);
    glTexCoord2f(0,1); glVertex2f(-1, 1);
  glEnd();

  glPopMatrix;
end;




procedure SAPPart.setTypus(const typus: SXState);
begin
  settings.typus := typus;
end;


procedure SAPPart.setPosition(const pos: SXVertex2D);
begin
  settings.pos := pos;
end;


procedure SAPPart.setRotation(const rot: SXFloat);
begin
  settings.rot := rot;
end;


procedure SAPPart.setSize(const size: SXFloat);
begin
  settings.size := size;
end;


procedure SAPPart.setColor(const color: SXColorRGB);
begin
  settings.color := color;
end;


procedure SAPPart.setDensity(const density: SXFloat);
begin
  settings.density := density;
end;


procedure SAPPart.setAnimation(const addpos: SXVertex2D; const addrot, addsize: SXFloat; const addcolor: SXColorRGB; const adddensity: SXFloat);
begin
  settings.animation.addpos := addpos;
  settings.animation.addrot := addrot;
  settings.animation.addsize := addsize;
  settings.animation.addcolor := addcolor;
  settings.animation.adddensity := adddensity;
end;


procedure SAPPart.setAnimationMoveAlongRot(const movealongrot: SXVertex2D);
begin
  settings.animation.movealongrot := movealongrot;
end;


function SAPPart.getTypus: SXState;
begin
  result := settings.typus;
end;


function SAPPart.getPosition: SXVertex2D;
begin
  result := settings.pos;
end;


function SAPPart.getRotation: SXFloat;
begin
  result := settings.rot;
end;


function SAPPart.getSize: SXFloat;
begin
  result := settings.size;
end;


function SAPPart.getColor: SXColorRGB;
begin
  result := settings.color;
end;


function SAPPart.getDensity: SXFloat;
begin
  result := settings.density;
end;




function SAPPart.getVectorFromRotation: SXVertex2D;
var vector: SXVertex2D;
begin
  vector.x := sx.math._sin(settings.rot);
  vector.y := sx.math._cos(settings.rot);
  result := sx.math.normalizeVector(vector);
end;


procedure SAPPart.processAnimation;
var timefactor: SXFloat;
    vector, normal: SXVertex2D;
begin
  timefactor := sx.timer.getTimer;
  with settings do
  begin
    pos := sx.math.addVertices(pos, sx.math.multiplyVertex(animation.addpos, timefactor));
    rot := rot + animation.addrot * timefactor;
    size := size + animation.addsize * timefactor;
    color := sx.math.color.addColors(color, sx.math.color.multiplyColor(animation.addcolor, timefactor));
    density := density + animation.adddensity * timefactor;

    // Get movement vector
    if (animation.movealongrot.x <> 0) or (animation.movealongrot.y <> 0) then
    begin
      vector := getVectorFromRotation;
      normal.x := -vector.y;
      normal.y := vector.x;
     
      vector := sx.math.multiplyVertex(vector, animation.movealongrot.y);
      vector := sx.math.addVertices(vector, sx.math.multiplyVertex(normal, animation.movealongrot.x));
      pos := sx.math.addVertices(pos, sx.math.multiplyVertex(vector, timefactor));
    end;
  end;
end;


procedure SAPPart.deleteIfInvisible;
begin
  if (settings.size <= 0) or (settings.density <= 0) then
  begin
    delete;
  end;
end;


procedure SAPPart.onTimer;
begin
  sx.timer.incTimer(settings.lifetime);
  processAnimation;
  deleteIfInvisible;
end;




procedure SAPPart.delete;
begin
  SAParticle(getParent).deleteParticle(self);
end;


constructor SAPPart.Create(const parent: TObject);
begin
  inherited Create(parent, 'Particle Part');

  settings.typus := 0;
  settings.pos := sx.convert.Vertex2DOf(0, 0);
  settings.rot := 0;
  settings.size := 1;
  settings.color := sx.convert.ColorRGBOf(1, 1, 1);
  settings.density := 1;
  settings.animation.addpos := sx.convert.Vertex2DOf(0, 0);
  settings.animation.addrot := 0;
  settings.animation.addsize := 0;
  settings.animation.addcolor := sx.convert.ColorRGBOf(0, 0, 0);
  settings.animation.adddensity := 0;
  settings.animation.movealongrot := sx.convert.Vertex2DOf(0, 0);
  settings.lifetime := 0;
end;


destructor SAPPart.Destroy;
begin
  inherited;
end;


end.