DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
From: "El Barto" <ef00@luc.ac.be> You can try the code at the end of this mail ( you didn't provide an email address so I can't send it to you directly ) it's a hot napalm explosion. El Barto ef00@luc.ac.be Proud member of the #SkAS#: Skuld Appreciation Society - the Goddess of Debuggers! Official SkAS Page : http://www.luc.ac.be/~ef00/skas ---------------------------------------------------------------------------- MF's Page : http://www.luc.ac.be/~ef00 ---------------------------------------------------------------------------- Willem Romijn wrote in article <33ba0ae6.1704582@news.pi.net>... > Hi, > I'm looking for a cool graphics explosion effect. Perhaps something > like they do in Red Alert, is this a fractal of some kind? Of course > any other explosion effect will do, preferebly small ones. Please help > me out on this. > > TVMIA, Willem Romijn > -- --------------------------------------------- Code ----------------------------------------- /* * Particle, simple little particle simulation type program * By TH/5/6/97 */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <dos.h> #include <conio.h> #define RANDOM(n) (((float)rand() / (float)RAND_MAX)*(n)) #define NUMPARTICLE 5000 void RoundToInt(int *dest, float val); #pragma aux RoundToInt=\ "fistp DWORD [eax]"\ parm nomemory [eax] [8087]\ modify exact [8087]; typedef struct { float x; float y; float dirx; float diry; int colour; } PARTICLE; char *vga = (char *) 0xA0000L; char *buffer = NULL; int ytable[200]; PARTICLE *particles; float gravity = 0.1; /* * Function: AllocateMemory * Purpose : Allocate the memory needed for the program: a double buffer, * : and a particle buffer * Input : Nothing * Output : 1 / 0 */ int AllocateMemory(void) { if((buffer = (char *) malloc(64000)) == NULL) return 0; if((particles = (PARTICLE *) malloc(NUMPARTICLE*sizeof(PARTICLE))) == NULL) { free(buffer); return 0; } return 1; } /* * Function: KaBoom * Purpose : Make an explosion at the centre-bottom of the screen * Input : Nothing * Output : Nothing */ void KaBoom(void) { int i; float len, lx, ly, dist; for(i=0; i<NUMPARTICLE; i++) { particles[i].x = 160; particles[i].y = 180; particles[i].dirx = RANDOM(2) - 1; particles[i].diry = -RANDOM(5); dist = RANDOM(5); lx = particles[i].dirx; ly = particles[i].diry; len = sqrt(lx*lx + ly*ly); /* We need to normalize the vector to give us a direction * vector, then find a random length of the vector, to give * a nice, non-uniform distribution */ if(len == 0.0) len = 0.0; else len = 1.0 / len; particles[i].dirx *= len*dist; particles[i].diry *= len*dist; particles[i].colour = 255; } } /* * Function: RandomKaBoom * Purpose : Make a big explosion, at a random place on the screen * Input : Nothing * Output : Nothing */ void RandomKaBoom(void) { int i; float len, lx, ly, dist; int x, y; x = RANDOM(319); y = RANDOM(180); for(i=0; i<NUMPARTICLE; i++) { particles[i].x = x; particles[i].y = y; particles[i].dirx = RANDOM(3) - 1.5; particles[i].diry = RANDOM(3) - 1.5; dist = RANDOM(5); lx = particles[i].dirx; ly = particles[i].diry; len = sqrt(lx*lx + ly*ly); if(len == 0.0) len = 0.0; else len = 1.0 / len; particles[i].dirx *= len*dist; particles[i].diry *= len*dist; particles[i].colour = 255; } } /* * Function: PaintParticle * Purpose : Paint a single particle to the screen * Input : Particle pointer * Output : The particle is written to the screen */ void PaintParticle(PARTICLE *particle) { int x, y; RoundToInt(&x, particle->x); RoundToInt(&y, particle->y); if((x < 0) || (x > 319) || (y < 0) || (y > 199)) return; buffer[ytable[y] + x] = particle->colour;; } /* * Function: InitGraphics * Purpose : Set up the graphics card * Input : Nothing * Output : Nothing */ void InitGraphics(void) { union REGS regs; int i; regs.x.eax = 0x13; int386(0x10, ®s, ®s); /* Here, we make a nice palette, that fades from red->yellow->white, * giving the usual spread of colours seen in an explosion */ outp(0x3C8, 0); for(i=0; i<64; i++) { outp(0x3C9, i); outp(0x3C9, 0); outp(0x3C9, 0); } for(i=64; i<128; i++) { outp(0x3C9, 63); outp(0x3C9, i - 64); outp(0x3C9, 0); } for(i=128; i<256; i++) { outp(0x3C9, 63); outp(0x3C9, 63); outp(0x3C9, (i - 128) >> 1); } for(i=0; i<200; i++) ytable[i] = i*320; memset(buffer, 0, 64000); } /* * Function: PaintParticles * Purpose : Paint all of the particles in the system * Input : Nothing * Output : Nothing */ void PaintParticles(void) { int i; PARTICLE *part; part = particles; for(i=0; i<NUMPARTICLE; i++) { PaintParticle(part); part++; } } /* * Function: MoveParticles * Purpose : Move all the particles in the system * Input : Nothing * Output : Nothing */ void MoveParticles(void) { int i; PARTICLE *part; part = particles; for(i=0; i<NUMPARTICLE; i++) { part->x += part->dirx; part->y += part->diry; /* Check if the particle has collided with any of the screen * top or bottom edges. If so, reflect the direction, and * lose energy. If not, then just add gravity */ if(part->y > 180) { part->y = 180; part->dirx /= 4; part->diry = -part->diry / 2; } else if(part->y < 1) { part->y = 1; part->dirx /= 4; part->diry = -part->diry / 2; } else { part->diry += gravity; } if(part->x < 0) { part->x = 1; part->dirx = -part->dirx / 2; part->diry /= 4; } else if(part->x > 319) { part->x = 319; part->dirx = -part->dirx / 2; part->diry /= 4; } /* If the particle is near the bottom of the screen, we * make its colour random, to simulate the effect of the * particle dying, things catching fire, that kind of stuff */ if(part->y >= 179) part->colour = (rand() & 127) + 128; part++; } } /* * Function: CloseGraphics * Purpose : Shut down graphics operation * Input : Nothing * Output : Nothing */ void CloseGraphics(void) { union REGS regs; regs.x.eax = 3; int386(0x10, ®s, ®s); } /* * Function: BlurScreen * Purpose : Apply blurring to the screen. This is what gives the screen * : Its explosion-like look. Without blurring, it looks very * : plain * Input : Nothing * Output : Screen is blurred */ void BlurScreen(void) { char *row1, *row2, *row3; int x, y, colour; for(y=1; y<182; y++) { row1 = buffer + ytable[y - 1]; row2 = buffer + ytable[y]; row3 = buffer + ytable[y + 1]; *row1++ = 0; *row2++ = 0; *row3++ = 0; for(x=1; x<319; x++) { colour = (*row1 + *row3 + *(row2 - 1) + *(row2 + 1)) / 4; colour -= 2; if(colour < 0) colour = 0; *row2 = colour; row1++; row2++; row3++; } *row1++ = 0; *row2++ = 0; *row3++ = 0; } } int main(int argc, char *argv[]) { int ok = 1; printf("KABOOM! A great big explosion, followed by the land below"); printf(" being burnt to a crisp\n"); printf("Written by Tom Hammersley <tomh@globalnet.co.uk> '97\n"); printf("Press [K] during program to make another explosion\n"); printf("Press any key ...\n"); getch(); if(!AllocateMemory()) { printf("Can't allocate enough memory\n"); return 1; } InitGraphics(); KaBoom(); do { PaintParticles(); MoveParticles(); BlurScreen(); memcpy(vga, buffer, 64000); if(kbhit()) { switch(tolower(getch())) { case 27: ok = 0; break; case 'k': RandomKaBoom(); break; } } } while(ok); CloseGraphics(); return 0; }
следующий фpагмент (3)|пpедыдущий фpагмент (1)
Korat wrote: > > I'm looking for information on particle systems, with > physics, primarily for modelling explosions.. > > (web searches have been kinda inconclusive :P) > > - To reply by Email, may address is: jecobb@netsync.net The main reason you will find little information is that particle systems are deceptively simple. Here are the basic steps : To render each particle in the particle system : Rotate and Translate Particle (Geometric Transformation) Test Particle against clipping window if outside then quit Perspective Divide Particle Plot Particle on the Screen Then each and every frame you will have to do physics for each and every particle in the system, which looks something like this : To move the particles : For Each Particle : Add Acceleration Vectors to Particle's Velocity Vector Translate Particle's Position by Velocity Vector Then for special particle effects Increment/Decrement Particle's lifespan Increment/Decrement or change in some way the Particle's color If lifespan elapses then destroy the particle For explosions, the particles should each be give a random velocity and all start at the center of the circle. How you choose the random velocity is very important. You can't just assign random values for the velocity's X,Y, and Z as this will result in a cube pattern. (Do you see why) You have to either assign a random angle and magnitude then convert that in to a velocity or take the random, incorrect velocity vector and normalize it. This will give you a spherical distribution instead of a cube, but all the particles will have the same magnitude of velocity. To correct this, you can scale the velocity by another random factor afterwards. This will give you a sherical distribution that you can use for the positions and the velocities. For fiery Quake-like explosions, you probably want the particles to be not affected by gravity. The true art of making particle systems look good lies in tweaking the random distribution of colors and tweaking the change in colors and intensities and particle lifespan. It is all about a lot of tweaking. The problem with a particle system like this is that it cannot support too many particles without slowing down. Quake's particle systems have around 500 particles, but they make them 4 pixels in area to make the system look more dense than it really is. That is another problem : the higher the resolution, you need to add either more particles (slowing it down) or make the particles larger (making it look worse) to keep the same density. I got some firework-type particle explosions working in a simple graphic engine of my own design that are Z-buffer rendered, and I used about 1,000-3,000 particles per explosion. It can get somewhat slow on my P60 when 3 or 4 explosions are on the screen at once. I hope that helps. Jake Cannell

Всего 2 фpагмент(а/ов) |пpедыдущий фpагмент (2)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".