Hello once again
This code snippet of mine is for those who rearly use the CurveValue function due to not being sure how to use it, and there are also extra curve value functions supplied that my interest others who are more experienced.
For anyone who wants to move or animate something smoothly, and to then suddenly reposition or change a value (or object)
instantly to something (or somewhere) else. Check out the 'CutOff' functions in the snippet.
For anyone new, generally the CurveValue command will smoothly change one value to another, each time it is called. The smoothness is determined by how high the integer speed value is in DBPRO (or how low it is in GDK as far as I can see).
You may also use a ratio of 0.0 - 1.0 for the speed parameter of the [CurveValueByRatio] function to adjust your value according to the floating point ratio; where 1.0 = 100%.
Media files and project
This requires media files because it also uses CurveValue commands to play music and sounds at different volumes, so please
download the latest verion here.
`\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\///////////////////////////////////////////
` \\\ B I N A R y M O D U L A R . C O M ///
` \\\ ///
` \\\=====================================================================///
` ||| C U R V E V A L U E |||
` |||--------------------------------------------------------------------|||
` ||| K I T © 2011 |||
` |||====================================================================|||
` /// \\\
` /// \\\
`||| VERSION: 1.0 LANGUAGE: DARK BASIC PROFESSIONAL |||
`||| __________________________________________________________ |||
`||| AUTHOR: Chris Tate [ Modern Man ? ] |||
`||| __________________________________________________________ |||
`||| WEBSITE: www.binarymodular.com |||
`||| __________________________________________________________ |||
`||| EMAIL: [email protected] |||
`||| __________________________________________________________ |||
`||| FORUM: ? |||
`||| __________________________________________________________ |||
`||| HELP: ? |||
`||| __________________________________________________________ |||
`||| |||
`||| |||
` \\\ __________________________________________________________ ///
` \\\ ///
` \\\=====================================================================///
` \\\===================================================================///
global BCutOffOccured as boolean ` Ensure that this global is declared
` Load music
//---------------------------------------------------
print "Press any key when ready" : wait key : cls
global MusicBeat = 21 : load sound "MusicBeat.wav", MusicBeat
global MusicBeatReverb = 22 : load sound "MusicBeatReverb.wav", MusicBeatReverb ` Played in the distance. Probably best with a mono (distant) sounding file
global MusicRiff = 23 : load sound "MusicRiff.wav", MusicRiff
global MusicBassline = 24 : load sound "MusicBassline.wav", MusicBassline
` The following floats will store volume settings which we will curve towards
` We must store the destination and current volume respectively. We cannot use [sound volume()] return value because it is an integer
global MusicBeat#
global MusicBeatVolume#
global MusicBeatReverb#
global MusicBeatReverbVolume#
global MusicRiff#
global MusicRiffVolume#
global MusicBassline#
global MusicBasslineVolume#
global MusicDistance#
` Load sound effects
for newSound = 1 to 5
load 3dsound "DropSphere.wav", newSound + 5
load 3dsound "Cutoff.wav", newSound
set sound volume newSound, 75
set sound volume newSound + 5, 75
next newSound
// Use curve value to interpolate camera movement
#constant CAM_TARGET 1
#constant CAM_POS 2
null = make vector3(CAM_TARGET)
null = make vector3(CAM_POS)
//---------------------------------------------------
SetupScene()
//---------------------------------------------------
loopId = 0
shake# = 0
global ForeColour : ForeColour = rgb( 100,255,100)
//---------------------------------------------------
set sound volume MusicBeatReverb, 0
set sound volume MusicBassline, 0
set sound volume MusicRiff, 0
loop sound MusicBeat
loop sound MusicBeatReverb
loop sound MusicBassline
loop sound MusicRiff
do
if loopId > 3600000 then loopId = 0
` Reset object positions
for resetObject = 1 to 4 : reposition( resetObject ) : next resetObject
repeat
` Handle music
//------------------------------------------
MusicDistance# = abs( camera position x() + camera position y() + camera position z() )
if MusicDistance# <> 0 then MusicDistance# = MusicDistance# / 3
// Curve each volume
MusicBeat# = limit( 100-MusicDistance#, 0, 90 )
MusicBeatVolume# = curveValueByRatio( 0.01, MusicBeat#, MusicBeatVolume# )
set sound volume MusicBeat, MusicBeatVolume#
MusicBeatReverb# = limit( MusicDistance#*8, 0, 70 )
MusicBeatReverbVolume# = curveValueByRatio( 0.01, MusicBeatReverb#, MusicBeatReverbVolume# )
set sound volume MusicBeatReverb, MusicBeatReverbVolume#
MusicRiff# = limit( MusicRiff# + upkey() - downkey(), 0, 100) ` Adjust with input
MusicRiffVolume# = curveValueByRatio( 0.01, MusicRiff#, MusicRiffVolume# )
set sound volume MusicRiff, MusicRiffVolume#
MusicBassline# = limit( MusicBassline# + rightkey() - leftkey(), 0, 100) ` Adjust with input
MusicBasslineVolume# = curveValueByRatio( 0.01, MusicBassline#, MusicBasslineVolume# )
set sound volume MusicBassline, MusicBasslineVolume#
position listener camera position x(), camera position y(), camera position z()
rotate listener camera angle x(), camera angle y(), camera angle z()
` Draw display
//------------------------------------------
inc loopId
DrawFPS()
DrawCameraPosition(1)
line 0,25,screen width(), 25
set cursor 0, 50
print "[Spacebar] to reset all"
print "[Number key] to reset the corresponding object"
print "[Return] key to add shake"
print "[left][right] arrow to decrease or increase music riff volume: "; str$(MusicRiff#,1) + "[" + str$( sound volume( MusicRiff )) + "]"
print "[up][down] arrow to increase or decrease music bassline volume: "; str$(MusicBassline#,1)+ "[" + str$( sound volume( MusicBassline ) ) + "]"
print "Move the camera using the mouse and notice the change in the beat"
` Handle each object
//------------------------------------------
for updateObject = 1 to 5
BCutOffOccured = 0
` Read positions
//---------------------------------------------------
x# = object position x( updateObject )
y# = object position y( updateObject )
z# = object position z( updateObject )
// why not generate code like this by simply typing 'dbp gp:updateObject' at www.binarymodular.com
//--------------------------------------------------
` Move down
select updateObject
case 1
y# = curveValue( 2, y#, 50)
endcase
case 2
y# = curveCutoffValue( 0.001, y#, 3, 5, 50)
endcase
case 3
y# = curveCutoffValueTo( 3, 3, y#, 3.1, 5, 50)
endcase
case 4
y# = curveCutoffValueTo( 13, 0, y#, 1, 5, 150)
endcase
case 5
y# = curveValueByRatio( 0.01, 2, y#)
endcase
endselect
` Update object
position object updateObject, curveValue( x#, x#+(sin(loopId)*shake#), 50), curveValue( y#, y#+(sin(loopId)*shake#*0.5), 50), curveValue( z#, z#+(cos(loopId)*shake#), 50)
` To keep things easy to read, play sounds in a seperate select statement. Not the quickest method.
if BCutOffOccured
position sound updateObject, x#, y#, z#
set sound speed updateObject, rnd( 1500 ) + 15000 ` Make more realistic by preventing each sound sounding the exactly the same
play sound updateObject
endif
next updateObject
ink 0, 0
for infoStep = 1 to 2
for infoObject = 1 to 5
DrawInfo(infoObject, infoStep)
next infoObject
ink ForeColour, 0
next infoStep
` Update camera
//--------------------------------------------------
set vector3 CAM_TARGET, x vector3(1) + (mousemovex() * 0.1), y vector3(1) + (mousemovey() * 0.1), z vector3(1) + (mousemovez() * 0.1)
set vector3 to camera position CAM_POS ,0
newCamX# = curveValue( x vector3( CAM_TARGET ), x vector3( CAM_POS ), 100 )
newCamY# = curveValue( y vector3( CAM_TARGET ), y vector3( CAM_POS ), 100 )
newCamZ# = curveValue( z vector3( CAM_TARGET ), z vector3( CAM_POS ), 100 )
position camera newCamX#, newCamY#, newCamZ#
`
` Omit the previous block and use the following to see the difference
`position camera camera position x() + (mousemovex() * 0.1), camera position y() + (mousemovey() * 0.1), camera position z() + (mousemovez() * 0.1)
point camera 0, 0, 0
` Handle lights
//--------------------------------------------------
for updateLight = 1 to 3
` Read light position
x# = light position x( updateLight )
y# = light position y( updateLight )
z# = light position z( updateLight )
` Orbit lights
select updateLight
case 1
x# = sin( wrapvalue(loopId * 0.5) ) * 10
y# = 7
z# = cos( wrapvalue(loopId * 0.5) ) * 4
endcase
case 2
x# = sin( wrapvalue(loopId * 0.2) ) * 4
y# = 7 + sin( wrapvalue(loopId * 0.2) ) ` Swivle this one a little on the Y axis
z# = cos( wrapvalue(loopId * 0.2) ) * 10
endcase
case 3
x# = 0.0
y# = sin( wrapvalue(loopId * 0.5) ) * 5 ` Notice by using y as reference, we are orbiting vertically
z# = cos( wrapvalue(loopId * 0.5) ) * 15
SET SHADOW POSITION updateLight, x#, y#, z#
endcase
endselect
` Update light position
position light updateLight, x#, y#, z#
position object updateLight + 10, x#, y#, z#
next updateLight
//------------------------------------------
` Handle individual reset
reposition( val( entry$() ) )
clear entry buffer
` Add shake
inc shake#, returnkey() * rnd(4) + returnkey()
shake# = curveCutOffValue( 0, shake#, 0, 2, 30 )
` Finish this loop
sync
` Reset when spacekey is pressed
until spacekey()
loop
//---------------------------------------------------
/////////////////////////////////////////////////////////////////////////
function CutoffValue( destination#, value#, cutOffFrom#, cutOffTo# )
value# = CutOffValueTo( 0.0, value#, cutOffFrom#, cutOffTo# )
endfunction value#
/////////////////////////////////////////////////////////////////////////
function CutoffValueTo( resetValue#, value#, cutOffFrom#, cutOffTo# )
if value# => cutOffFrom# and value# <= cutOffTo#
BCutOffOccured = 1
exitfunction resetValue#
else
BCutOffOccured = 0
endif
endfunction value#
/////////////////////////////////////////////////////////////////////////
function CurveCutoffValue( destination#, value#, cutOffFrom#, cutOffTo#, speed# )
value# = CutoffValue( destination#, value#, cutOffFrom#, cutOffTo# )
if value# <> destination# then value# = curveValue( destination#, value#, speed# )
endfunction value#
/////////////////////////////////////////////////////////////////////////
function CurveCutoffValueTo( resetValue#, destination#, value#, cutOffFrom#, cutOffTo#, speed# )
value# = CutoffValueTo( resetValue#, value#, cutOffFrom#, cutOffTo# )
value# = curveValue( destination#, value#, speed# )
endfunction value#
/////////////////////////////////////////////////////////////////////////
function CurveValueByRatio( ratio#, destination#, value# )
if value# = destination# then exitfunction destination#
if ratio# = 0 then exitfunction value#
dist# = abs( destination# - value# )
if destination# > value#
inc value#, dist# * ratio#
else
dec value#, dist# * ratio#
endif
endfunction value#
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function reposition( id )
if id > 0 and id <= 5
doSound = id + 5
position object id, (id - 3) * 6, 12, 0
set sound speed doSound, rnd( 500 ) + 15000 ` Make more realistic by preventing each sound sounding the exactly the same
position sound doSound, (id - 3.5) * 6, 10, 0
play sound doSound
endif
endfunction
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function DrawInfo( updateObject, offset )
label$ = str$(updateObject) + ": [" + str$(y#,1) + "]"
center text object screen x(updateObject) + offset, object screen y(updateObject) + offset, label$
if offset = 1 then exitfunction
print ` Newline
select updateObject
case 1
print "Object "; updateObject; " CurveValue"
endcase
case 2
print "Object "; updateObject; " CurveCutoffValue"
endcase
case 3
print "Object "; updateObject; " CurveCutoffValueTo"
endcase
case 4
print "Object "; updateObject; " CurveCutoffValueTo ( Repositioned )"
endcase
case 5
print "Object "; updateObject; " CurveValueByRatio"
endcase
endselect
endfunction
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function Limit( value#, min#, max# )
if value# < min# then exitfunction min#
if value# > max# then exitfunction max#
endfunction value#
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function DrawFPS()
text 0, 0, "FPS: " + str$( screen fps() ) + " Delta: " + str$( screen fps() / 60 , 2 )
endfunction
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function DrawCameraPosition( decimals )
text$ = "Camera:" + str$(camera position x(),decimals) + ", " + str$(camera position y(),decimals) + ", " + str$(camera position z(),decimals)
textWidth = text width( text$ )
text screen width() - text width( text$ ), 0, text$
endfunction
// www.binarymodular.com
//=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=
function SetupScene()
set display mode 1024, 768, 32
print "One moment please..."
color backdrop 0
` Sort out the environment
//-----------------------------------------
set text size 12
autocam off : fog off
set vector3 CAM_TARGET, 0,5,-25 ` Move camera towards this position
sync on : sync rate 60
set ambient light 0
set normalization on
for newObject = 1 to 5
make object sphere newObject, 2 : reposition(newObject)
color object newObject, rgb( newObject * 50, newObject * 50, newObject * 50 )
set shadow shading on newObject
set object ambience newObject, 0
next newObject
make object plane 6, 40, 20 : xrotate object 6, 270 :
` Make some lights liven the scene
//--------------------------------------------------
for newLight = 1 to 3
make light newLight
select newlight
case 1 : colour = rgb( rnd( 255 ), rnd( 0 ), rnd( 0 ) ) : endcase
case 2 : colour = rgb( rnd( 0 ), rnd( 0 ), rnd( 255 ) ) : endcase
case 3 : colour = rgb( rnd( 0 ), rnd( 255 ), rnd( 0 ) ) : endcase
endselect
color light newLight, colour
set shadow light newLight, 0, 0, 0, 50
make object sphere newLight + 10, 0.2 : color object newLight + 10, colour : set object emissive newLight + 10, colour
next newLight
//---------------------------------------------------
endfunction
remstart
You are permitted to use this snippet file freely in your projects
Chris Tate - [email protected]
Try my other snippets and tutorials at: www.binarymodular.com. You will also find a code generator.
Generate:
object position x( a ), object position y( a ), object position z( a )
object position x( b ), object position y( b ), object position z( b )
object position x( c ), object position y( c ), object position z( c )
with:
dbp op3:a,a,a,b,b,b,c,c,c
remend