 |
| Author |
Message |
kaedroho
User
Joined: Tue Aug 21st 2007
Location: Oxford,UK
|
|
Posted: 13th Jul 2009 17:40 Edited: 18th Jul 2009 12:48 |
| link | toggle |
Let me introduce to you my solution to a well known problem with muzzleflashes!
The problem is caused by having a single plain to represent a flash. Sometimes the camera cannot see it! Most people make loads of flashes and point them in different directions, hoping that the camera will see one. This doesnt look very good, plus the extra polys cant help on FPS.
My solution uses only one flash object. And uses Matrix algebra to calculate which direction the flash should face. Its alot like billboarding but it will work in any angle you point it in.
Demo Attached.
Enjoy!
+ Code Snippet// MUZZLE FLASH SYSTEM
// VERSION 1 - 13th July 2009
// PROGRAMMED BY KARL HOBLEY
// YOU MAY USE THIS CODE IN COMMERCIAL AND NON COMMERCIAL PROJECTS FREE OF CHARGE!
// www.blitzwerks.co.uk
type MF_Main
objnum as dword
objnum2 as dword
vector as dword
matrix1 as dword
matrix2 as dword
matrix3 as dword
muzzleflashes as dword
endtype
type MF_Muzzleflash
created as dword
objnum as dword
exists as boolean
endtype
function MF_Start(freeobject,freeobject2,tex1,tex2,freevector,freematrix1,freematrix2,freematrix3)
//UDT
global MF_Main as MF_Main
//Make flash object
MF_Main.objnum=freeobject
make object plain freeobject,20,13
i=0
repeat
inc i
until object exist(i)=0
t=0
repeat
inc t
until mesh exist(t)=0
make object plain i,10,10
make mesh from object t,i
delete object i
add limb freeobject,1,t
rotate limb freeobject,0,270,270,0
offset limb freeobject,0,0.5,0,10
delete mesh t
set object cull freeobject,0
set object light freeobject,0
texture limb freeobject,1,tex1
texture limb freeobject,0,tex2
exclude object on freeobject
set object transparency freeobject,2
disable object zwrite freeobject
//Make another flash object (with limbs swapped)
MF_Main.objnum2=freeobject2
make object plain freeobject2,10,10
i=0
repeat
inc i
until object exist(i)=0
t=0
repeat
inc t
until mesh exist(t)=0
make object plain i,20,13
make mesh from object t,i
delete object i
add limb freeobject2,1,t
rotate limb freeobject2,1,270,90,0
offset limb freeobject2,1,0.5,0,10
delete mesh t
set object cull freeobject2,0
set object light freeobject2,0
texture limb freeobject2,0,tex1
texture limb freeobject2,1,tex2
exclude object on freeobject2
set object transparency freeobject2,2
disable object zwrite freeobject2
//Make Matrices and a vector
MF_Main.vector=freevector
MF_Main.matrix1=freematrix1
MF_Main.matrix2=freematrix2
MF_Main.matrix3=freematrix3
n=make vector4(MF_Main.vector)
n=make matrix4(MF_Main.matrix1)
n=make matrix4(MF_Main.matrix2)
n=make matrix4(MF_Main.matrix3)
//Make array
global dim MF_Muzzleflash(0) as MF_Muzzleflash
endfunction
function MF_Update()
//Loop through muzzleflashs
for i=1 to MF_Main.muzzleflashes
//Check if the muzzle flash exists
if MF_Muzzleflash(i).exists
//Work how long its been alive
time=timer()-MF_Muzzleflash(i).created
//If its too old, kill it
if time>40
delete object MF_Muzzleflash(i).objnum
MF_Muzzleflash(i).exists=0
endif
endif
next i
endfunction
function MF_CreateMuzzleflash(objectnumber,x#,y#,z#,xang#,yang#,zang#,camx#,camy#,camz#,size#)
//Allocate muzzleflash
muzzleflash=MF_Intern_FindFreeMuzzleFlash()
MF_Muzzleflash(muzzleflash).created=timer()
MF_Muzzleflash(muzzleflash).objnum=objectnumber
//Set Matrices
rotate x matrix4 MF_Main.matrix2,-xang#/57.2958
rotate y matrix4 MF_Main.matrix3,-yang#/57.2958
//Multiply matrices
set identity matrix4 MF_Main.matrix1
multiply matrix4 MF_Main.matrix1,MF_Main.matrix1,MF_Main.matrix3
multiply matrix4 MF_Main.matrix1,MF_Main.matrix1,MF_Main.matrix2
//Set vector to cameras current position
set vector4 MF_Main.vector,camx#-x#,camy#-y#,camz#-z#,0
//Transform vector with matrix
transform vector4 MF_Main.vector,MF_Main.vector,MF_Main.matrix1
//Get values
camx#=x vector4(MF_Main.vector)
camy#=y vector4(MF_Main.vector)
camz#=z vector4(MF_Main.vector)
//Get angle
angle#=atanfull(camx#,camy#)
//Instance the source object
if camz#>0
instance object objectnumber,MF_Main.objnum2
else
instance object objectnumber,MF_Main.objnum
endif
//Rotate back
rotate limb objectnumber,1,0,0,rnd(359)
//Position the muzzleflash
position object objectnumber,x#,y#,z#
//Rotate the muzzleflash
rotate object objectnumber,xang#,yang#,0
roll object right objectnumber,angle#
endfunction
function MF_Intern_FindFreeMuzzleFlash()
//Loop through current muzzleflashes to see if we can recyccle any
for i=1 to MF_Main.muzzleflashes
if MF_Muzzleflash(i).exists=0
MF_Muzzleflash(i).exists=1
exitfunction i
endif
next i
//Allocate a new muzzleflash
inc MF_main.muzzleflashes
muzzleflash=MF_main.muzzleflashes
array insert at bottom MF_Muzzleflash(0)
MF_Muzzleflash(muzzleflash).exists=1
endfunction muzzleflash
|
Back to top
 |
|
Maxicube
User
Joined: Thu Jul 16th 2009
Location: Cyberspace
|
I'm not sure how to use this example...
I don't think its DBP
|
Back to top
 |
|
BMacZero
User
Joined: Fri Dec 30th 2005
Location: E:/N_America/USA/ California/South
|
|
Posted: 17th Jul 2009 16:24 Edited: 17th Jul 2009 16:24 |
| link | toggle |
Awesome! I'll be sure to save this for my planned FPS project...maybe even for Fields if it's fast enough  .
I did notice a little problem with the transparency on the objects:
It's a DBP glitch, I thought the fix was to use transparency mode 5 but that doesn't seem to be working.
Diggsey: I have a spine and memory, but one memorable guy says he hates me. What am I? + Code SnippetA book!
|
Back to top
 |
|
kaedroho
User
Joined: Tue Aug 21st 2007
Location: Oxford,UK
|
|
Posted: 17th Jul 2009 18:36 Edited: 18th Jul 2009 12:04 |
| link | toggle |
Quote: "I'm not sure how to use this example...
I don't think its DBP "
It is DBP. Its just my weird coding style.
BMacZero, Thanks.
The problem can be solved, but it isn't easy, You have to detect if the camera is in front of or behind the backplane. Then disable the Zwrite. Then using the information gathered by detecting weather or not the camera is in front or behind, swap the limbs to change the render order. Otherwise you might get parts rendering in front of others. Also, Disabling Zwrite will not only mess up limb render orders, but also object render orders. The only way to solve that is doing 'Set global object creation 6' at the beginning of your code. This should make DBPro render all the further away objects first, and the nearest last which will correct this issue.
After all that, you will have the best muzzle flash system possible in DBPro.
(I havn't actually tested the above, just made it up on the spot, may test later though)
EDIT: ADDING IN THE ABOVE!
|
Back to top
 |
|
|
Google Ad
AdBot
Joined: Aug 26th 2002
Location: Everywhere
|
|
Back to top
 |
|
kaedroho
User
Joined: Tue Aug 21st 2007
Location: Oxford,UK
|
Alright, a quick update.
Now, it checks if the camera is infront of or behind the back plane. If its infront, the limbs get swapped. This solves the bug reported by BmacZero.
+ Code Snippet// MUZZLE FLASH SYSTEM
// VERSION 1 - 13th July 2009
// PROGRAMMED BY KARL HOBLEY
// YOU MAY USE THIS CODE IN COMMERCIAL AND NON COMMERCIAL PROJECTS FREE OF CHARGE!
// www.blitzwerks.co.uk
type MF_Main
objnum as dword
objnum2 as dword
vector as dword
matrix1 as dword
matrix2 as dword
matrix3 as dword
muzzleflashes as dword
endtype
type MF_Muzzleflash
created as dword
objnum as dword
exists as boolean
endtype
function MF_Start(freeobject,freeobject2,tex1,tex2,freevector,freematrix1,freematrix2,freematrix3)
//UDT
global MF_Main as MF_Main
//Make flash object
MF_Main.objnum=freeobject
make object plain freeobject,20,13
i=0
repeat
inc i
until object exist(i)=0
t=0
repeat
inc t
until mesh exist(t)=0
make object plain i,10,10
make mesh from object t,i
delete object i
add limb freeobject,1,t
rotate limb freeobject,0,270,270,0
offset limb freeobject,0,0.5,0,10
delete mesh t
set object cull freeobject,0
set object light freeobject,0
texture limb freeobject,1,tex1
texture limb freeobject,0,tex2
exclude object on freeobject
set object transparency freeobject,2
disable object zwrite freeobject
//Make another flash object (with limbs swapped)
MF_Main.objnum2=freeobject2
make object plain freeobject2,10,10
i=0
repeat
inc i
until object exist(i)=0
t=0
repeat
inc t
until mesh exist(t)=0
make object plain i,20,13
make mesh from object t,i
delete object i
add limb freeobject2,1,t
rotate limb freeobject2,1,270,90,0
offset limb freeobject2,1,0.5,0,10
delete mesh t
set object cull freeobject2,0
set object light freeobject2,0
texture limb freeobject2,0,tex1
texture limb freeobject2,1,tex2
exclude object on freeobject2
set object transparency freeobject2,2
disable object zwrite freeobject2
//Make Matrices and a vector
MF_Main.vector=freevector
MF_Main.matrix1=freematrix1
MF_Main.matrix2=freematrix2
MF_Main.matrix3=freematrix3
n=make vector4(MF_Main.vector)
n=make matrix4(MF_Main.matrix1)
n=make matrix4(MF_Main.matrix2)
n=make matrix4(MF_Main.matrix3)
//Make array
global dim MF_Muzzleflash(0) as MF_Muzzleflash
endfunction
function MF_Update()
//Loop through muzzleflashs
for i=1 to MF_Main.muzzleflashes
//Check if the muzzle flash exists
if MF_Muzzleflash(i).exists
//Work how long its been alive
time=timer()-MF_Muzzleflash(i).created
//If its too old, kill it
if time>40
delete object MF_Muzzleflash(i).objnum
MF_Muzzleflash(i).exists=0
endif
endif
next i
endfunction
function MF_CreateMuzzleflash(objectnumber,x#,y#,z#,xang#,yang#,zang#,camx#,camy#,camz#,size#)
//Allocate muzzleflash
muzzleflash=MF_Intern_FindFreeMuzzleFlash()
MF_Muzzleflash(muzzleflash).created=timer()
MF_Muzzleflash(muzzleflash).objnum=objectnumber
//Set Matrices
rotate x matrix4 MF_Main.matrix2,-xang#/57.2958
rotate y matrix4 MF_Main.matrix3,-yang#/57.2958
//Multiply matrices
set identity matrix4 MF_Main.matrix1
multiply matrix4 MF_Main.matrix1,MF_Main.matrix1,MF_Main.matrix3
multiply matrix4 MF_Main.matrix1,MF_Main.matrix1,MF_Main.matrix2
//Set vector to cameras current position
set vector4 MF_Main.vector,camx#-x#,camy#-y#,camz#-z#,0
//Transform vector with matrix
transform vector4 MF_Main.vector,MF_Main.vector,MF_Main.matrix1
//Get values
camx#=x vector4(MF_Main.vector)
camy#=y vector4(MF_Main.vector)
camz#=z vector4(MF_Main.vector)
//Get angle
angle#=atanfull(camx#,camy#)
//Instance the source object
if camz#>0
instance object objectnumber,MF_Main.objnum2
else
instance object objectnumber,MF_Main.objnum
endif
//Rotate back
rotate limb objectnumber,1,0,0,rnd(359)
//Position the muzzleflash
position object objectnumber,x#,y#,z#
//Rotate the muzzleflash
rotate object objectnumber,xang#,yang#,0
roll object right objectnumber,angle#
endfunction
function MF_Intern_FindFreeMuzzleFlash()
//Loop through current muzzleflashes to see if we can recyccle any
for i=1 to MF_Main.muzzleflashes
if MF_Muzzleflash(i).exists=0
MF_Muzzleflash(i).exists=1
exitfunction i
endif
next i
//Allocate a new muzzleflash
inc MF_main.muzzleflashes
muzzleflash=MF_main.muzzleflashes
array insert at bottom MF_Muzzleflash(0)
MF_Muzzleflash(muzzleflash).exists=1
endfunction muzzleflash
|
Back to top
 |
|
BMacZero
User
Joined: Fri Dec 30th 2005
Location: E:/N_America/USA/ California/South
|
That seems to fix it, with one little glitch - you switched the two objects, so the wrong one is given render priority. I just switched the two object numbers:
MF_Main.objnum2=freeobject
MF_Main.objnum=freeobject2
And it worked great! Thanks!
Diggsey: I have a spine and memory, but one memorable guy says he hates me. What am I? + Code SnippetA book!
|
Back to top
 |
|
TuPP3
User
Joined: Fri Jan 26th 2007
Location: [+--]FINLAND
|
I did muzzleflash by making plane object in my gun model to tip of my weapon barrel, then just show and hide that limb for second after shot.
But I found it troublesome if you are trying to modify that limb, like rotate and resize it after each shot, rotational axis is gun center axis, which makes muzzle plane swivel off the tip of the gun.
|
Back to top
 |
|
kaedroho
User
Joined: Tue Aug 21st 2007
Location: Oxford,UK
|
This code makes sure the plane always faces the camera. A big problem with muzzle flashes is that you have to get loads of plains facing different directions to beable to see it.
The technique is alot like billboarding, but more complicated. The gun has control of the objects x and y rotation but the system has to try and find the z rotation.
|
Back to top
 |
|
gbark
User
Joined: Fri Oct 14th 2005
Location: US - Virginia
|
Nice!
This system could also be used for a lot of things, not just muzzleflashes. A simple lightsaber using just one "hilt" object and a muzzleflash-plain representing the beam would look mighty good with this.
|
Back to top
 |
|
You must be logged-in to post messages to this forum. You can register an account for free. Or click here to login.
Enter a word or phrase to search our Forum for:
|
|
 |