Posted: 14th Oct 2003 1:07
Ive just downloaded the newest version of this code and i must say its some of the most impressive coding work ive seen - not only does the level run smoothly wherever you point the camera now (as opposed to the ropyness of the last version), but its also accurate and fast - WELL DONE!!!

You deserve an award for this
Posted: 14th Oct 2003 7:54
You can adjust the height at which you can "walk" onto an object.

As for controlling the camera while falling, that's a simple IF statement to correct that.

To figure out the angle of what you can/can't walk up, take the distance check to the wall and the distance of the height check. If you lower the height check or lengthen the wall check, you can't walk up as steep of a ramp. Using geometry, you can figure out any angle you want.

This snippet was made to mainly show how you can do sliding collision with just an .X object. I wasn't aiming for a complete FPS engine.

-Kensupen
Posted: 15th Oct 2003 3:40
how about a get ground height thing? get the height of the lowest triangle at a particular x,z coordinate
Posted: 15th Oct 2003 18:06
Your code is awesome!
But I have one problem I can't figure out, my object y position
is 0 and chartht#=50, this puts my object in the air. If I change
charht# to 0 then I cant' walk up ramp. Any suggestions??
Posted: 18th Oct 2003 10:47
@Chris
To do a "get ground height" using just any .X model, just use ht#=1000000-intersect object(1,player position x(#),1000000,player position z(#),player position x(#),-1000000,player position z(#)
I'm not 100% positive this code works, but it's the general idea. (Just wrote it from memory)

@Dugzilla
Leave charht# at 50 and just position your object at where I am positioning the camera -charht#. That way you still get the ramp angle you can walk up, but you just position the object at a "dummy" height.

-Kensupen
Posted: 18th Oct 2003 16:34
I erckon this should be built into U6.....

It would be cool if there was a 'GET FLOOR HEIGHT' command, bit like the get matrix height command, but it found the height of a 3d object.... this could eradicate the need for the intersect object bit in this code....just a suggestion. Probably a stupid one.
Posted: 19th Oct 2003 8:04
isnt that what intersect object is for moonshime.?
Posted: 19th Oct 2003 17:06
is there a way to make it so it takes a steeper ramp to fly off it a bit? right now, on a very shallow ramp u bump off the ground for a bit and it feels wierd when ur bumping up and down going down a little hill.

P.S. i still dont get your get ground height
im new to programming, esp new to dbp
could you please give a tested line of code?
Posted: 19th Oct 2003 21:45
Just thought it might be faster. Sorry. And its MoonshiNe, indi.
Posted: 20th Oct 2003 4:55
I still can't get an object to work with this code. If someone could
write an object in with this that would be great. I spent the whole
dang weekend on this......
Posted: 20th Oct 2003 7:51
@Chris:
The way you "walk" down a ramp is that you move forward and then gravity pulls you down. If you don't want it to bump on a small ramp, you'll have to increase gravity. (I think that is a bad idea though) Everquest has this same issue. Every hill you walk down, you constantly fall after you move. As for the Ground height of a model, read up on how Intersect Object works. It's how I made this snippet to begin with. Just play around with the command and built-in objects to see how it works, then apply that to a model.

@Dugzilla:
If I had time, I'd make a new snippet for using a model that walks around the area. As it stands, I just started a new job and it's taking up a lot of my time. I haven't been able to program for a month now. It's too bad the RGT forums got erased. Someone was working on just what you are asking for. I'll let you know if I find the time to convert it to a cube moving around the map.

-Kensupen
Posted: 20th Oct 2003 16:43
Thanks for the help kensupen! I'll keep trying different things,
something has to work sooner or later.
Posted: 20th Oct 2003 16:44
I'll keep an eye open for any new posts that regard sliding
collision.
Posted: 21st Oct 2003 0:17
This may help,
Here is Kensupen's code changed over to object collision. Of course this means that there is no collision for the camera. What it needs is both, camera and object collision.
Movement is with the mouse buttons. Use Kensupen's level files.

gbuilder.

+ Code Snippet
`***************************
`.X Model sliding collision
`Dev of Kensupen's Code by gbuilder
`***************************

hide mouse
set display mode 640,480,16
autocam off
set image colorkey 255,0,255
sync on
sync rate 0
color backdrop 6
set camera range 1,10000
set ambient light 75

`collider
make object sphere 2,20 : show object 2

`level
load object "mslevel.x",1 : position object 1,0,0,0
set object transparency 1,2

dir$=get dir$()
`Height object is off the ground
charht#=30
`speed to move
spd#=3
`set the radius for collisions
radius#=10.0
`set initial object position
position object 2,0,charht#,0
yrotate object 2,20

`number of checks
checks=8
if checks<4 then checks=4
if checks>360 then checks=360
`width of the angles
angwidth=360/checks
`make arrays for collision data
dim ang#(checks-1,2)
dim sort#(checks-1,2)

do
set cursor 0,0
print "FPS:",screen fps()
`print "x:";camera position x()
`print "y:";camera position y()
`print "z:";camera position z()

`Get initial positions and a revert set
oldx#=object position x(2)
oldz#=object position z(2)
cx#=object position x(2)
cy#=object position y(2)
cz#=object position z(2)
ca#=object angle y(2)
`mousestuff
if mouseclick()=1
cx#=newxvalue(cx#,ca#,spd#)
cz#=newzvalue(cz#,ca#,spd#)
position object 2,cx#,cy#,cz#
endif
if mouseclick()=2 then move object 2,-2
ca#=wrapvalue(ca#+mousemovex())
yrotate camera ca#
yrotate object 2,ca#
`pitch
pitch#=wrapvalue(pitch#+mousemoveY()): xrotate camera pitch#
if pitch#>90 and pitch#<=180 then pitch#=90
if pitch#<270 and pitch#>180 then pitch#=270

`The main sliding collision code
gosub _collision
`My code to walk up a ramp if the angle isn't too steep
gosub _ramp

`Camera follows the object
posx#=object position x(2)
posy#=object position y(2)
posz#=object position z(2)
angle#=object angle y(2)
set camera to follow posx#,posy#,posz#,angle#,60,charht#+50,1,1

sync
loop

_ramp:
`get positions again
cx#=object position x(2)
cz#=object position z(2)
`Get your old height
oldht#=object position y(2)
`calc new height using intersect object from the old height down charht# units
sub#=intersect object(1,cx#,oldht#,cz#,cx#,oldht#-(charht#*2),cz#)
ht#=(oldht#+charht#)-sub#
if sub#=0 then ht#=charht#
`do some gravity
grav#=grav#-0.25
`if you are going up a ramp
if oldht#+grav#<ht#
grav#=0.0
position object 2,cx#,ht#,cz#
else
`if you are falling
ht#=oldht#+grav#
position object 2,cx#,ht#,cz#
endif
return

_collision:
`collision
for x=0 to checks-1
chx#=newxvalue(cx#,x*angwidth,100)
chz#=newzvalue(cz#,x*angwidth,100)
ang#(x,1)=intersect object(1,cx#,cy#,cz#,chx#,cy#,chz#)
if ang#(x,1)=0 then ang#(x,1)=999999
ang#(x,2)=x*angwidth
sort#(x,1)=ang#(x,1)
sort#(x,2)=ang#(x,2)
next x
`sort the array to find the closest object and it's degrees
for x=0 to checks-2
for y=x+1 to checks-1
if ang#(x,1)>ang#(y,1)
temp#=ang#(x,1)
temp2#=ang#(x,2)
ang#(x,1)=ang#(y,1)
ang#(x,2)=ang#(y,2)
ang#(y,1)=temp#
ang#(y,2)=temp2#
endif
next x
next y
`find +-90 degrees from the closest one for anti-shake
prev=wrapvalue(ang#(0,2)-90)/angwidth
nxt=wrapvalue(ang#(0,2)+90)/angwidth
newd#=radius#-ang#(0,1)
newa#=wrapvalue(ang#(0,2)-180)
newd1#=radius#-sort#(prev,1)
newa1#=wrapvalue(sort#(prev,2)-180)
newd2#=radius#-sort#(nxt,1)
newa2#=wrapvalue(sort#(nxt,2)-180)
`if you are less than radius from a wall, push you out to 20 from it
if ang#(0,1)<radius# and ang#(0,1)>0.0
repx#=newxvalue(cx#,newa#,newd#)
repz#=newzvalue(cz#,newa#,newd#)
position object 2,repx#,cy#,repz#
endif
cx#=object position x(2)
cz#=object position z(2)
`this is if you are coming into a corner, this pushes you sideways
if sort#(prev,1)<radius# and sort#(prev,1)>0.0
repx1#=newxvalue(cx#,newa1#,newd1#)
repz1#=newzvalue(cz#,newa1#,newd1#)
position object 2,repx1#,cy#,repz1#
endif
cx#=object position x(2)
cz#=object position z(2)
`and the other way. above is left, this is right
if sort#(nxt,1)<radius# and sort#(nxt,1)>0.0
repx2#=newxvalue(cx#,newa2#,newd2#)
repz2#=newzvalue(cz#,newa2#,newd2#)
position object 2,repx2#,cy#,repz2#
endif
return
Posted: 21st Oct 2003 2:14
gbuilder,
I've come across this code with a sphere that works well with
itself but when you try to use lets say the colonel z charactor
that came with dbpro,there is a height issue I haven't been able to
figure out. try to set that sphere so it is at ground level not 30
unit in the air and see if you have collision problems with ramp. Or
try out colonel yourself to see if you get a problem like I do?
Posted: 21st Oct 2003 3:36
Yep, I imported the colz.x character and with a bit of tweeking it's on the ground and going up the ramp. Here's what I did..

Change.. 'position object 2,0,charht#,0' to.. 'position object 2,0,charht#-30,0'
Then I lifted up the level a little to 'load object "mslevel.x",1 : position object 1,0,35,0'
Oh, I also reduced the size of the colz.x character by 50%..

Woops, just looked at this again and the character is not exactly on the ground...

gbuilder
Posted: 21st Oct 2003 7:38
This code works great with camera but man it is a pain with an object. I haven't any luck with it today,maybe tommorrow..
Dugzilla
Posted: 21st Oct 2003 14:48
hey, this is better than Sonic's DLL... and works the same. Except for the sliding part. But anyway, I modified it a bit for some gravity jump effect... it's meant for jumping off ramps. It doesn't work right currently but it's neat how it is. I'll be modifying it to get it to work correctly...
Posted: 26th Oct 2003 19:25
This code is brilliant, there was one thing which prevented me using levels which have minus y co-ordinates (The camera doesn't go below the specified camera height.) so I fixed it for you.

I have basically made my own ramp code based on the supplied, I left the original in there and it can be activated again by removing the remark (so long as you rem out my part). I also added some different movement controlls so that its more fps orientated and a variable to edit the gravity.

You won't notice any difference on the map supplied as its lowest point is 0. Here is the map I tested it with and found the problem, try both ramp codes and try walking off the bridge from the side.

http://stateproperty.users.btopenworld.com/xcol.zip

Very small (250kb) contains the map and the source not required, i'll post the source here too.

+ Code Snippet
`***************************
`.X Model sliding collision
`By Kensupen and Lokidecat
`Nerdsoft Creations (C) 2003
`***************************
`This uses all native DBPro commands to give a user sliding collision
`against ANY .X model to slide on ANY angle. It works almost as good as BSP
`collision, except for height. If you can walk onto an object, it just
`puts you at that height. I might try to advance the code later to give
`a smooth height adjustment.
`***************************
`Edited by RefuG :)
`***************************

rem Main Program Setup
sync on : sync rate 60 : autocam off : hide mouse : position mouse 320,240
set camera range 1,5000 : set ambient light 75

set image colorkey 255,0,255

rem load level
load object "mslevel.x",1
set object light 1,0
set object transparency 1,1

rem Main Program Variables
rem camera height from ground
cameraheight# = 50 : rem For RefuG's Ramp Code (I like readable variables :p)
charht#=50 : rem For Kensupen's Ramp Code
rem camera speed
movespeed# = 3
rem collision radius
radius# = 10.0
rem gravity
gravity# = 5

rem Set The Initial Camera Position And Rotation
position camera 0,50,0
rotate camera 0,180,0


rem Number Of Checks
`the lower this number is, the more off the collisions will be vs. any rotated object.
`also, the lower the number, the more speed it runs at.
`lowest for rotated collision is 4(non rotated/box collision) max is 360, but 360 is WAAAY slow
`I'd advide is you play with this number to keep with a multiple of 4
checks=8
if checks<4 then checks=4
if checks>360 then checks=360
`width of the angles
angwidth=360/checks
`make arrays for collision data
dim ang#(checks-1,2)
dim sort#(checks-1,2)

rem Main Loop
do

   set cursor 0,0
   rem Centers Mouse
   position mouse 320,240

   rem Get Initial Positions And A Revert Set
   oldx#=camera position x()
   oldz#=camera position z()
   cx#=camera position x()
   cy#=camera position y()
   cz#=camera position z()
   cay#=camera angle y()

   rem Camera Movement
   `forwards (w)
   if keystate(17)=1
      cx# = newxvalue(cx#,wrapvalue(cay#),movespeed#)
      cz# = newzvalue(cz#,wrapvalue(cay#),movespeed#)
   endif
   `backwards (s)
   if keystate(31)=1
      cx# = newxvalue(cx#,wrapvalue(cay#-180),movespeed#)
      cz# = newzvalue(cz#,wrapvalue(cay#-180),movespeed#)
   endif
   `left (a)
   if keystate(30)=1
      cx# = newxvalue(cx#,wrapvalue(cay#-90),movespeed#)
      cz# = newzvalue(cz#,wrapvalue(cay#-90),movespeed#)
   endif
   `right (d)
   if keystate(32)=1
      cx# = newxvalue(cx#,wrapvalue(cay#+90),movespeed#)
      cz# = newzvalue(cz#,wrapvalue(cay#+90),movespeed#)
   endif

   rem camera rotation
   yrotate camera camera angle y() + mousemovex()*0.3
   xrotate camera camera angle x() + mousemovey()*0.3
   rem stops mouse from going upside down
   if wrapvalue(camera angle x(0))>90 and wrapvalue(camera angle x(0))<180 then xrotate camera 0,90
   if wrapvalue(camera angle x(0))>180 and wrapvalue(camera angle x(0))<280 then xrotate camera 0,280
   rem Camera Position + Gravity
   position camera cx#,cy#-gravity#,cz#


   rem Refresh And Debugging
   rem Show the camera angle
   print "Camera angle:",camera angle y()
   rem The main sliding collision code
   gosub _collision
   rem Kensupen Ramp Code
   `gosub _ramp
   rem RefuG Ramp Code
   gosub _gravity
   rem A just in case reset
   if spacekey()=1 then position camera 0,200,0

   set cursor 0,100 : print camera position x();" : ";camera position y();" : ";camera position z()

   sync
loop


_collision:

   rem Get Positions Again
   cx#=camera position x()
   cy#=camera position y()
   cz#=camera position z()
   `make 72 collision points. You can use more or less, but this number seems to work good.
   `These are vectors every 5 degrees from the camera position out.
   `They return the distance when they hit an object
   for x=0 to checks-1
      chx#=newxvalue(cx#,x*angwidth,100)
      chz#=newzvalue(cz#,x*angwidth,100)
      ang#(x,1)=intersect object(1,cx#,cy#,cz#,chx#,cy#,chz#)
      if ang#(x,1)=0 then ang#(x,1)=999999
      ang#(x,2)=x*angwidth
      sort#(x,1)=ang#(x,1)
      sort#(x,2)=ang#(x,2)
   next x

   rem sort the array to find the closest object and it's degrees
   for x=0 to checks-2
      for y=x+1 to checks-1
         if ang#(x,1)>ang#(y,1)
            temp#=ang#(x,1)
            temp2#=ang#(x,2)
            ang#(x,1)=ang#(y,1)
            ang#(x,2)=ang#(y,2)
            ang#(y,1)=temp#
            ang#(y,2)=temp2#
         endif
      next x
   next y

   `This is the closest wall and what degrees you would face to see it
   print "Angle to closest wall:",ang#(0,2)
   print "Distance to that wall:",ang#(0,1)

   `find +-90 degrees from the closest one for when you walk into a corner so it doesn't shake
   prev=wrapvalue(ang#(0,2)-90)/angwidth
   nxt=wrapvalue(ang#(0,2)+90)/angwidth
   newd#=radius#-ang#(0,1)
   newa#=wrapvalue(ang#(0,2)-180)
   newd1#=radius#-sort#(prev,1)
   newa1#=wrapvalue(sort#(prev,2)-180)
   newd2#=radius#-sort#(nxt,1)
   newa2#=wrapvalue(sort#(nxt,2)-180)

   `if you are less than radius from a wall, push you out to 20 from it
   if ang#(0,1)<radius# and ang#(0,1)>0.0
      repx#=newxvalue(cx#,newa#,newd#)
      repz#=newzvalue(cz#,newa#,newd#)
      position camera repx#,cy#,repz#
   endif
   cx#=camera position x()
   cz#=camera position z()

   `this is if you are coming into a corner, this pushes you sideways
   if sort#(prev,1)<radius# and sort#(prev,1)>0.0
      repx1#=newxvalue(cx#,newa1#,newd1#)
      repz1#=newzvalue(cz#,newa1#,newd1#)
      position camera repx1#,cy#,repz1#
   endif
   cx#=camera position x()
   cz#=camera position z()

   `and the other way. above is left, this is right
   if sort#(nxt,1)<radius# and sort#(nxt,1)>0.0
      repx2#=newxvalue(cx#,newa2#,newd2#)
      repz2#=newzvalue(cz#,newa2#,newd2#)
      position camera repx2#,cy#,repz2#
   endif
   return

rem Kensupen Ramp Code
_ramp:
   rem get positions again
   cx#=camera position x()
   cz#=camera position z()

   rem Get your old height
   oldht#=camera position y()

   rem calc new height using intersect object from the old height down charht# units
   sub#=intersect object(1,cx#,oldht#,cz#,cx#,oldht#-(charht#*2),cz#)
   ht#=(oldht#+charht#)-sub#
   if sub#=0 then ht#=charht#
   rem do some gravity
   grav#=grav#-0.25
   rem if you are going up a ramp
   if oldht#+grav#<ht#
      grav#=0.0
      position camera cx#,ht#,cz#
   else
   `if you are falling
       ht#=oldht#+grav#
       position camera cx#,ht#,cz#
   endif
return

rem RefuG Ramp Code
_gravity:
   rem Get Positions Again
   cx#=camera position x()
   cz#=camera position z()

   rem Get Your Old Height
   oldht#=camera position y()
   `cy#=camera position y()

   rem Finds The Distance From The Camera To The Floor
   sub#=intersect object(1,cx#,oldht#,cz#,cx#,oldht#-cameraheight#,cz#)

   rem If A Number Smaller Than The Specified Floor Height Is Returned Then...
   if sub# < cameraheight#
      cy#=(oldht#+cameraheight#)-sub#
      rem reposition camera
      position camera cx#,cy#,cz#
   endif

   rem If The Camera Is Not "Touching" The Floor (i.e. Floor Height + Specified Camera Heght) Then
   if sub# = 0
      rem reset camera position
      position camera cx#,oldht#,cz#
   endif

   rem debugging
   set cursor 0,80 : print sub#
return


[Edit] The Source Button didnt work and I can't edit it so ^^ hopefully this will + A Quick Fix now in the above zip too
Posted: 26th Oct 2003 23:01
Refug,
Nice work. Smooth stairs now with that new gravity code. Liked the demo level. Looks like it was made in cshop. When I turned on the lightmap, my old geforce2 struggled a little. Looks good though.

gbuilder.