Radioactive decay demo:
Ok, I thought that might get your attention but now that you're here, what this is is actually much more than some kind of graphical effect. It's the result of my first work with Sparky's DLL, and it's the kind of thing I've always wanted to make. I'll leave it up to you to check it out, but there is some explaining to do beforehand:
1.) There is some supplied media because that's the demonstration of the program. You could supply your own, just make sure it's inside-out (faces facing inward). I'm sure you'd know how to change the code to change which object gets loaded; it's right at the start of the program. There are a few shapes to try, but start with the default of using "shape3.x" the way the program's written.
2.) You can press the 1,2, and 3 keys for different camera views. 1=front (default/start), 2=side, and 3=top. It doesn't really matter which view you use, but they do give you quick frame of reference when you want to know which way you're looking. If you have a mouse wheel, roll it to move the camera forward. There is no back because DB's Move Camera doesn't use negative values and I could never figure that out. If you can do 'move forward'(+), then why not 'move backward'(-)? Anyway...left and right arrows move camera left and right, and up and down keys, camera up+down. The only thing missing is pulling the camera back, but between all the controls you should be able to get the camera positioned where you want. Sometimes you have to use Camera Forward in small steps to get to exactly the point you want to look from...
3.) When you throw a ball, its speed comes from how far away the (1st) bounce point is. So, if you're very close and you let loose a ball, it will start out slower. Using the 1,2,3 keys moves the camera farther out to start with, so if you choose one of these views and shoot a ball, it will start out with a higher speed and head towards its target. It's made this way just to give a variable way to send the spheres moving at different volocities without having to do some kind of input to make that change. It's just about camera distance which makes (made) it easy to test different velocties.
Now, the whole problem all along with this program has been that it would miss bounces, and seeing that disappointed me very much. It might make a few successful bounces, but then I'd always see a ball fly off into space, and my disappointment grew. But then I found an error in my logic and it was in the adding of the object's velocity at the time of collision detection. There was an error in which variables I was using, but then I figured that out. Now it's working the best I've ever seen it, so I wanted to see if there was any feedback on it...
Try starting out at the very first default camera location at the start of the program, and fire a couple of balls. Cool. Fire a few more. Awesome. Get it up 50 or 60 balls. 99 is the max but I wouldn't try it.
It's kinda cool to watch it at this point. It's what I've dreamed of making for a long time. The weird shape is to 'really test it out'.
Ok, now quit and restart the program. Maybe fire a few slow balls, but then use the 1 key to get to that far front camera view. Now fire a couple or few balls. See, they're going quite a bit faster. Here comes the test: do they stay inside. Get like 40 or 50 fast balls flying around in there. I was like "Hey look, it's working....", then a single ball goes flying off into space. If you watch it for a while, it looks like radioactive decay
Well, the purpose should be pretty obvious: What comments does anyone have about this? Please bear in mind that since I changed the manual collision detecting area, probably about 30-40% of the code inside the FOR-NEXT loop to check each object is probably useless now. Like I don't think I need to be using Sparky's once for each object once per pass through the loop any more. Plus I'm sure there's other stuff inside there that's no longer needed, so all that could likely be removed. And you can safely ignore all the mumbo-jumbo data's displayed on the screen. I was using them during the initial testing and I'm not even sure they're right any more
. It's not cleaned up yet, just working...sorta. It does however show alot about the techniques of manual collision detecting, at least that's what I learned from it. And as great as I think Sparky's DLL is (I couldn't have done this without it), it shows the need for a (built-in) collision detection system that can handle things like this. As good as I thought I've done here, it's still prone to errors (apparently?), which is why I think DB could really help out its users by helping us out in this area...
REM Project: SPARKYcollision
REM Created: 11/1/05 1:49:35 AM
REM
REM ***** Main Source File *****
REM
set display mode 800,600,32
`InitD3D
sync on
sync rate 0
hide mouse
autocam off
Position Camera 0,0,-30
Point Camera 0,0,0
Set Camera FOV 35
randomize timer()
Global oldmousez
`make object cylinder 1,10
Load Object "shape3.x",100
`color object 100,rgb(200,0,0)
`Load image "wild001.bmp",1,1
`Texture Object 100,1
`Make Object Cube 1,10 : YRotate Object 1,45 : Position Object 1,3,0,0
Set Normalization ON
Set Object Collision to Polygons 100
setupComplexObject 100,0,2 : rem or `setupObject 1,0,0
Load Sound "bounce.wav",1
`make a bullet marker
make object plain 101,2,2
color object 101,rgb(255,255,255)
hide object 101
rem make a white image, since coloring doesn't work very well with no light
make memblock 1,16
write memblock dword 1,0,1
write memblock dword 1,4,1
write memblock dword 1,8,32
write memblock dword 1,12,rgb(255,255,255)
make image from memblock 1,1
delete memblock 1
texture object 101,1
set object light 101,0
numobjects=0
Dim objectvelocityx#(99)
Dim objectvelocityy#(99)
Dim objectvelocityz#(99)
Dim newx#(99)
Dim newy#(99)
Dim newz#(99)
Dim oldx#(99)
Dim oldy#(99)
Dim oldz#(99)
Dim normx#(99)
Dim normy#(99)
Dim normz#(99)
Dim bouncex#(99)
Dim bouncey#(99)
Dim bouncez#(99)
Dim coldist#(99)
Dim disttraveled#(99)
Dim colpointx#(99)
Dim colpointy#(99)
Dim colpointz#(99)
Dim ithit(99)
Dim recolx#(99)
Dim recoly#(99)
Dim recolz#(99)
Dim checkdist#(99)
Dim disttocol#(99)
Dim wallx#(99)
Dim wally#(99)
Dim wallz#(99)
objectvelocityx#(1)=0
objectvelocityy#(1)=0
objectvelocityz#(1)=.01
do
yrotate camera camera angle y()+(mousemovex()/10.0)
xrotate camera camera angle x()+(mousemovey()/10.0)
position mouse 400,300
rem spacebar for rotation
if spacekey()=1 and rotatetimer+300<timer()
rotatetimer = timer()
rotate object 100,rnd(359),rnd(359),rnd(359)
rem updates the object, including scaling if allowed.
updateObject 100
hide object 101
endif
hide object 101
if mouseclick()=1 `and timer()>shoottime
` If timer()>shoottime
rem get our simple collision vector. Moving the camera is what allows us to see the interect
rem 'down the line of sight' of the camera (wherever it's pointed)
oldx#=camera position x()
oldy#=camera position y()
oldz#=camera position z()
oldx#(numobjects)=camera position x()
oldy#(numobjects)=camera position y()
oldz#(numobjects)=camera position z()
move camera 200
x#=camera position x()
y#=camera position y()
z#=camera position z()
move camera -200
collide=intersectObject(0,0,oldx#,oldy#,oldz#,x#,y#,z#,0) : rem see the collision point down the line of sight
newx#=getStaticCollisionX() : rem retrieve the location of the intersection
newy#=getStaticCollisionY()
newz#=getStaticCollisionZ()
rem get collision normal
normx#=getCollisionNormalX() : rem retrieve the normal of the polygon being intersected with.
normy#=getCollisionNormalY()
normz#=getCollisionNormalZ()
position object 101,newx#+normx#/100.0,newy#+normy#/100.0,newz#+normz#/100.0
point object 101,newx#+normx#,newy#+normy#,newz#+normz#
show object 101
if collide=100 and timer()>shoottime
For oo=1 to 99
rem find a free object to use
If Object Exist(oo)=0 Then ob=numobjects+1 : Exit
Next oo
`INC numobjects
numobjects=oo
rem get the collision point
newx#(numobjects)=getStaticCollisionX() : rem retrieve the location of the intersection
newy#(numobjects)=getStaticCollisionY()
newz#(numobjects)=getStaticCollisionZ()
colpointx#(numobjects)=newx#
colpointy#(numobjects)=newy#
colpointz#(numobjects)=newz#
rem get collision normal
normx#(numobjects)=getCollisionNormalX() : rem retrieve the normal of the polygon being intersected with.
normy#(numobjects)=getCollisionNormalY()
normz#(numobjects)=getCollisionNormalZ()
bouncex#(numobjects)=getCollisionBounceX()
bouncey#(numobjects)=getCollisionBounceY()
bouncez#(numobjects)=getCollisionBounceZ()
`~~~~~~~~~~~~~
Make Object Sphere numobjects,.3,10,10
Position Object numobjects,camera position x(),camera position y(),camera position z()
shoottime=timer()+500
distancex#=Camera Position X()-newx#(numobjects)
distancey#=Camera Position Y()-newy#(numobjects)
distancez#=Camera Position Z()-newz#(numobjects)
coldist#(numobjects)=( (distancex#)^2 + (distancey#)^2 + (distancez#)^2 )
`wallx#(numobjects)=newx#(numobjects)
`wally#(numobjects)=newy#(numobjects)
`wallz#(numobjects)=newz#(numobjects)
objectvelocityx#(numobjects)=-distancex#/400.00 : rem 200 is just a slow-down'er, it's not required by anything. (higher=slower)
objectvelocityy#(numobjects)=-distancey#/400.00
objectvelocityz#(numobjects)=-distancez#/400.00
disttocol#(numobjects)= SQRT( distancex#^2 + distancey#^2 + distancez#^2 )
checkdist#(numobjects)=200.000
`~~~~~~~~~~~~~
numobjects=ob
endif
endif
`base movement on time, then you can get the object's position at any point in time (1 pass thru the loop)
For o=1 to numobjects
` disttocol#(o)=SQRT( (Object Position X(o)-newx#(o))^2 + (Object Position Y(o)-newy#(o))^2 + (Object Position Z(o)-newz#(o))^2 )
If Object Exist(o)
`This is a different way of handling the collision detection that is supposedly faster. Instead of
`using the (slow) SQRT function, do away with the SQRT and just compare the distances squared.
`The last version before this was Bouncing08.dba.
` disttocol#(o)= ( coldist#(o) - ( (Object Position X(o)+objectvelocityx#(o)-wallx#(o))^2 + (Object Position Y(o)+objectvelocityy#(o)-wally#(o))^2 + (Object Position Z(o)+objectvelocityz#(o)-wallz#(o))^2 ) )
disttocol#(o)= ( coldist#(o) - ( (Object Position X(o)+objectvelocityx#(o)-newx#(o))^2 + (Object Position Y(o)+objectvelocityy#(o)-newy#(o))^2 + (Object Position Z(o)+objectvelocityz#(o)-newz#(o))^2 ) )
If coldist#(o)-disttocol#(o)<0.035 `and ithit(o)=0 : rem Main collision
`If Object Hit(o,0)=100
Position Object o,wallx#(o)+((Object Position X(o)+objectvelocityx#(o))-wallx#(o)),wally#(o)+((Object Position Y(o)+objectvelocityy#(o))-wally#(o)),wallz#(o)+((Object Position Z(o)+objectvelocityz#(o))-wallz#(o))
oldx#(o)=object position x(o)
oldy#(o)=object position y(o)
oldz#(o)=object position z(o)
disttraveled#(o)=0.000
`move_camera(1)
`Play Sound 1
ithit(o)=1
v#=SQRT(objectvelocityx#(o)^2 + objectvelocityy#(o)^2 + objectvelocityz#(o)^2)
x#=bouncex#(o)/checkdist#(o)
y#=bouncey#(o)/checkdist#(o)
z#=bouncez#(o)/checkdist#(o)
objectvelocityx#(o)=v#*x#
objectvelocityy#(o)=v#*y#
objectvelocityz#(o)=v#*z#
`^~~~~ First, re-adjust the object's velocities because of the bounce.
oldx#=object position x(o) : rem Set-up a new intersect, this time using the object's current position,
oldy#=object position y(o) : rem to a point somewhere further out on the path of the object, after the
oldz#=object position z(o) : rem bounce....using new direction after the bounce.
x#=object position x(o)+objectvelocityx#(o)*500
y#=object position y(o)+objectvelocityy#(o)*500
z#=object position z(o)+objectvelocityz#(o)*500
checkdist#(o)=SQRT( (oldx#-x#)^2 + (oldy#-y#)^2 + (oldz#-z#)^2 )
`V~~~ Get some new values for the next bounce...
collide=intersectObject(0,0,oldx#,oldy#,oldz#,x#,y#,z#,0) : rem see the collision point down the line of sight
if collide=100
newx#(o)=getStaticCollisionX() : rem retrieve the location of the intersection
newy#(o)=getStaticCollisionY()
newz#(o)=getStaticCollisionZ()
` If (newx#(o)=colpointx#(o)) and (newy#(o)=colpointy#(o)) and (newz#(o)=colpointz#(o))
` Text 200,580,"We'er waiting because ther sin't a new collision point ey"
` Sync : wait key
` colpointx#(99)=newx#(o)
` colpointy#(99)=newy#(o)
` colpointz#(99)=newz#(o)
` EndIF
else
` newx#(o)=object position x(o)+objectvelocityx#(o)*200
` newy#(o)=object position y(o)+objectvelocityy#(o)*200
` newz#(o)=object position z(o)+objectvelocityz#(o)*200
newx#(o)=0
newy#(o)=0
newz#(o)=0
endif
rem get collision normal
normx#(o)=getCollisionNormalX() : rem retrieve the normal of the polygon being intersected with.
normy#(o)=getCollisionNormalY()
normz#(o)=getCollisionNormalZ()
bouncex#(o)=getCollisionBounceX() : rem This is the big one....
bouncey#(o)=getCollisionBounceY()
bouncez#(o)=getCollisionBounceZ()
coldist#(o)=( (oldx#-newx#(o))^2 + (oldy#-newy#(o))^2 + (oldz#-newz#(o))^2 )
If Object Exist(144)=0 : rem Shows where the next bounce will occur
Make Object Sphere 144,.1,10,10 : Color Object 144,RGB(0,255,0)
EndIF
If Object Exist(144)=1
` Position Object 144,newx#(o),newy#(o),newz#(o)
Position Object 144,newx#(numobjects),newy#(numobjects),newz#(numobjects)
EndIF
EndIF
`find wall point
oldx#=object position x(o)
oldy#=object position y(o)
oldz#=object position z(o)
x#=oldx#+(-normx#(o)*500) : rem <<<<<< 500 is the scale of distance you can check for collision intersect!!
y#=oldy#+(-normy#(o)*500)
z#=oldz#+(-normz#(o)*500)
collide=intersectObject(0,0,oldx#,oldy#,oldz#,x#,y#,z#,0) : rem see the collision point down the line of sight
wallx#(o)=getStaticCollisionX() : rem retrieve the location of the intersection
wally#(o)=getStaticCollisionY()
wallz#(o)=getStaticCollisionZ()
If Object Exist(145)=0 : rem Shows where on the wall normal
Make Object Sphere 145,.1,10,10 : Color Object 145,RGB(255,0,255)
EndIF
If Object Exist(145)=1
Position Object 145,wallx#(o),wally#(o),wallz#(o)
EndIF
Position Object o,Object Position X(o)+objectvelocityx#(o),Object Position Y(o)+objectvelocityy#(o),Object Position Z(o)+objectvelocityz#(o)
disttraveled#(o)=( (Object Position X(o)-oldx#(o))^2 + (Object Position Y(o)-oldy#(o))^2 + (Object Position Z(o)-oldz#(o))^2 )
If coldist#(o)-disttocol#(o)>0.03 Then ithit(o)=0
If disttocol#(o)>15000 Then Delete Object o
EndIF
Next o
Text 0,5,"numobjects:"+STR$(numobjects)
Text 0,35,"Distance X:"+LEFT$(STR$(distancex#),9)+" Distance Y:"+LEFT$(STR$(distancey#),9)+" Distance Z:"+LEFT$(STR$(distancez#),9)
Text 0,45,"Norm X:"+STR$(normx#)+" Norm Y:"+STR$(normy#)+" Norm Z:"+STR$(normz#)
Text 0,60,"Dist to spot :"+STR$(coldist#(numobjects))
Text 0,75,"Dist Traveled :"+STR$(disttraveled#(numobjects))
`
` Text 0,515,"Atan X:"+LEFT$(STR$(ATAN(normx#)),9)+" SIN X:"+LEFT$(STR$(SIN(normx#)),9)+" Cos X:"+LEFT$(STR$(COS(normx#)),9)
Text 0,530,"At X:"+LEFT$(STR$(newx#+normx#/100.0),9)+" At Y:"+LEFT$(STR$(newy#+normy#/100.0),9)+" At Z:"+LEFT$(STR$(newz#+normz#/100.0),9)
Text 0,545,"Bounce X:"+STR$(bouncex#)+" Bounce Y:"+STR$(bouncey#)+" Bounce Z:"+STR$(bouncez#)
Text 0,560,"Velocity X:"+STR$(objectvelocityx#(1))+" Velocity Y:"+STR$(objectvelocityy#(1))+" Velocity Z:"+STR$(objectvelocityz#(1))
move_camera(0)
ink rgb(255,0,0),0
circle 400,300,10
dot 400,300
ink rgb(255,255,255),0
sync
loop
end
delete memblock 10
`Don't forget to have at least one memblock command in the source somewhere!
Function move_camera(pause)
CAM:
yrotate camera camera angle y()+(mousemovex()/10.0)
xrotate camera camera angle x()+(mousemovey()/10.0)
position mouse 400,300
If inkey$()="1" Then Position Camera 0,0,-80 : Point Camera 0,0,0 : Rem Front
If inkey$()="2" Then Position Camera 0,-80,0 : Point Camera 0,0,0 : Rem Overhead
If inkey$()="3" Then Position Camera -80,0,0 : Point Camera 0,0,0 : Rem Side
if MouseZ()<>oldmousez Then Move Camera 1 : oldmousez=MouseZ()
If scancode()=200 Then Position Camera Camera Position X(),Camera Position Y()+.1,Camera Position Z() `: Point Camera 0,0,0
If scancode()=208 Then Position Camera Camera Position X(),Camera Position Y()-.1,Camera Position Z() `: Point Camera 0,0,0
If scancode()=203 Then Position Camera Camera Position X()-.1,Camera Position Y(),Camera Position Z() `: Point Camera 0,0,0
If scancode()=205 Then Position Camera Camera Position X()+.1,Camera Position Y(),Camera Position Z() `: Point Camera 0,0,0
If pause=1 and inkey$()<>"q" Then Sync : Goto CAM
EndFunction
http://www.geocities.com/crmnlelmnt/