TGC Codebase Backup



CatmullRom 2D and 3D Sample Code by ChipOne

3rd Sep 2003 17:54
Summary

This sample was created to test functionality in both 2D and 3D space and demonstrates simple use of the spline functions.



Description

CatmullRom Splines are great for curved paths and can be used to create great looking camera effects and such. They are also handy and used quite frequently in graphics applications for drawing and creating spline-based shapes. This code illustrates simple use of the supplied functions in both 2D and 3D.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    ` test catmull-rom  functionality
sync on
sync rate 30

testCatmullRom3DSplines()
testCatmullRom2DSplines()

end

function testCatmullRom3DSplines()
   ` set up 'constants' (just need them locally to identify
   ` the different vectors more easily while debugging
   v3_BEND1 as integer
   v3_ANCHOR1 as integer
   v3_ANCHOR2 as integer
   v3_BEND2 as integer
   v3_RESULT as integer

   ` assign the 'constants' their values
   v3_BEND1 = 1
   v3_ANCHOR1 = 2
   v3_ANCHOR2 = 3
   v3_BEND2 = 4
   v3_RESULT = 5

   ` create the five vectors needed for catmull-rom splines
   result = make vector3(v3_BEND1)
   result = make vector3(v3_ANCHOR1)
   result = make vector3(v3_ANCHOR2)
   result = make vector3(v3_BEND2)
   result = make vector3(v3_RESULT)

   ` put values into the vectors
   set vector3 v3_BEND1, -100, -400, -100
   set vector3 v3_ANCHOR1, -30, 0, -30
   set vector3 v3_ANCHOR2, 30, 0, 30
   set vector3 v3_BEND2, 100, 400, 100

   ` create the objects and draw them along the calculated spline
   for i = 1 to 50
      make object cube i, 1
      catmullrom vector3 v3_RESULT, v3_BEND1, v3_ANCHOR1, v3_ANCHOR2, v3_BEND2, 0.02*(i-1)
      position object i, x vector3(v3_RESULT), y vector3(v3_RESULT), z vector3(v3_RESULT)
   next i

   ` x axis reference
   make object box 51, 1, 1, 120
   color object 51, rgb(0,0,255)
   rotate object 51, 0, 90, 0
   ghost object on 51, 0

   ` y axis reference
   make object box 52, 1, 1, 120
   color object 52, rgb(255,255,0)
   rotate object 52, 90, 0, 0
   ghost object on 52, 0

   ` z axis reference
   make object box 53, 1, 1, 120
   color object 53, rgb(255,0,0)
   ghost object on 53, 0

   ` spline start/end reference points
   make object sphere 54, 2
   make object sphere 55, 2
   color object 54, rgb(255,0,0)
   color object 55, rgb(255,0,0)
   position object 54, 30, 0, 30
   position object 55, -30, 0, -30

   ` a tracking variable to spin the camera
   ang# = 0

   do

      ` rotate the camera around the outside radius of the spline and
      ` point it back to the centre
      inc ang#, 2.5
      position camera sin(ang#) * 90, 20, cos(ang#) * 90
      point camera 0, 0, 0

      ` output test information
      text 10, 10, "This test demonstrates that Catmull-Rom splines in 3D space are"
      text 10, 22, "calculating correctly.  The spline should be traced through 0,0,0"
      text 10, 34, "from from the negative X/Z quadrant to the positive X/Z quadrant."
      text 10, 54, "The start/end reference points are indicated by red spheres."
      text 10, 70, "   (Blue is X Axis, Yellow is Y Axis and Red is Z Axis)"
      text 10, screen height() - 30, "Press space to exit"
      sync

      ` exit condition
      if spacekey()
         ` the following prevents this test from affecting others by
         ` pausing for the duration of the space-key-press
         while spacekey():endwhile
         exit
      endif

   loop

   ` clean up objects
   for i = 1 to 55
      delete object i
   next i

   ` destroy vectors
   result = delete vector3(v3_BEND1)
   result = delete vector3(v3_ANCHOR1)
   result = delete vector3(v3_ANCHOR2)
   result = delete vector3(v3_BEND2)
   result = delete vector3(v3_RESULT)
endfunction

function testCatmullRom2DSplines()
   ` set up 'constants' (just need them locally to identify
   ` the different vectors more easily while debugging
   v2_BEND1 as integer
   v2_ANCHOR1 as integer
   v2_ANCHOR2 as integer
   v2_BEND2 as integer
   v2_RESULT as integer

   ` assign the 'constants' their values
   v2_BEND1 = 1
   v2_ANCHOR1 = 2
   v2_ANCHOR2 = 3
   v2_BEND2 = 4
   v2_RESULT = 5

   ` create the five vectors needed for catmull-rom splines
   result = make vector2(v2_BEND1)
   result = make vector2(v2_ANCHOR1)
   result = make vector2(v2_ANCHOR2)
   result = make vector2(v2_BEND2)
   result = make vector2(v2_RESULT)

   ` put values into the vectors
   set vector2 v2_BEND1, 320-420, -500
   set vector2 v2_ANCHOR1, 320-120, 200
   set vector2 v2_ANCHOR2, 320+120, 200
   set vector2 v2_BEND2, 320+420, 900

   ` x axis reference
   cls 0
   ink rgb(255, 0, 0), 0
   line 0, 200, 640, 200

   ` y axis reference
   ink rgb(0, 255, 0), 0
   line 320, 0, 320, 480

   ` spline start/end reference points
   ink rgb(0, 0, 255), 0
   circle 200, 200, 5
   circle 440, 200, 5

   ` create the objects and draw them along the calculated spline
   ink rgb(128,128,128), 0
   for i = 0 to 50
      catmullrom vector2 v2_RESULT, v2_BEND1, v2_ANCHOR1, v2_ANCHOR2, v2_BEND2, 0.02*i
      circle x vector2(v2_RESULT), y vector2(v2_RESULT), 3
   next i

   ` output test information
   ink rgb(255, 255, 255), 0
   text 10, 10, "This test demonstrates that Catmull-Rom splines in 2D space are"
   text 10, 22, "calculating correctly.  The spline should be traced through the"
   text 10, 34, "centre of the yellow and red crosshair."
   text 10, 54, "The start/end reference points are indicated by blue circles."
   text 10, 70, "   (Red is X Axis, Yellow is Y Axis)"
   text 10, screen height() - 30, "Press space to exit"
   sync

   ` exit condition
   wait key

   ` destroy vectors
   result = delete vector2(v2_BEND1)
   result = delete vector2(v2_ANCHOR1)
   result = delete vector2(v2_ANCHOR2)
   result = delete vector2(v2_BEND2)
   result = delete vector2(v2_RESULT)
endfunction