POV-Ray : Newsgroups : povray.advanced-users : Flying and bouncing debris : Re: Flying and bouncing debris Server Time
29 Jul 2024 14:25:45 EDT (-0400)
  Re: Flying and bouncing debris  
From: Tim Nikias
Date: 29 Sep 2002 12:39:42
Message: <3d972cce@news.povray.org>
I hope this doesn't wrap...

The usage is simple:
-Declare some variables
-Place object and call macro
-Done!

It supports different sized spheres, you can set maximum
of rebounces and the minimum speed an object needs to
have for an actual rebounce, otherwise the algorithm
simplifies itself by leaving some calculations away.

I think in some formulae I mixed some + and -, was pretty
hard tracking the mistake down...

Here's the code:

//My version:

//Environmental settings:
#declare Time=clock*5;
#declare Gravity=9.8;
#declare Ground_Height=0;
#declare Ground_Friction=.9;
#declare Rebounce_Threshold=.05;
#declare Rebounce_Amount=4;

//The macro
#macro Generate_Path()
 #local _Act_DirSpeed=Object_DirSpeed;
 #local _Act_Pos=Object_Start;
 #local _Act_Timer=Time;
 #local _Stay_On_Floor=false;
 #local _Reb_Counter=0;
 //Find a hit
 #local _Hit_Time=
((_Act_DirSpeed.y/Gravity) +
 sqrt(pow(_Act_DirSpeed.y/Gravity,2) +
((2*(_Act_Pos.y-Object_Radius-Ground_Height))/Gravity) ));
 //Compare to timer...
 #while (_Hit_Time<_Act_Timer & _Hit_Time>0 & !_Stay_On_Floor)
  //Get position and speed of impact
  #local _Act_Pos= (_Act_Pos + _Act_DirSpeed*_Hit_Time -
y*.5*Gravity*pow(_Hit_Time,2))*<1,0,1> +
y*(Ground_Height+Object_Radius+.001);
  #local _Act_DirSpeed=(_Act_DirSpeed-
(y*Gravity*_Hit_Time))*<1,-1,1>*Ground_Friction;
  //Check for speed-threshold
  #if (_Act_DirSpeed.y<Rebounce_Threshold) #local _Stay_On_Floor=true; #end
  //Get remaining time
  #local _Act_Timer=_Act_Timer-_Hit_Time;
  //Generate new hit-time
  #local _Root=
pow(_Act_DirSpeed.y/Gravity,2)+((2*(_Act_Pos.y-Object_Radius-Ground_Height))
/Gravity);
  #if (_Root>0)
   #local _Hit_Time=((_Act_DirSpeed.y/Gravity)+sqrt(_Root )); #else
   #local _Hit_Time=0; #end
  #if (_Hit_Time<0) #local _Hit_Time=0; #end
  //Counting the rebounces
  #local _Reb_Counter=_Reb_Counter+1;
  #if (_Reb_Counter=Rebounce_Amount) #local _Stay_On_Floor=true; #end
 #end
 //Place on floor if required...
 #if (!_Stay_On_Floor)
  #local
_Act_Pos=_Act_Pos+_Act_DirSpeed*_Act_Timer-y*.5*Gravity*pow(_Act_Timer,2);
#else
  #local
_Act_Pos=(_Act_Pos+_Act_DirSpeed*_Act_Timer-y*.5*Gravity*pow(_Act_Timer,2))*
<1,0,1>+y*(Ground_Height+Object_Radius); #end
 //Return
 (_Act_Pos)
#end

//Generates different sized spheres
#macro Rock_Macro()
sphere{0,Object_Radius pigment{rgb x}}
#end

#declare R=seed(1);

#declare C=0;
#while (C<20)

//POV will stop with an error-message if these aren't declared PRIOR the
macro-call
#declare Object_Radius=.2+.2*rand(R); //Will also be used for the Rock-Macro
#declare
Object_Start=vnormalize(<rand(R)*2-1,rand(R)*2-1,rand(R)*2-1>)*.2+y*2;
#declare
Object_DirSpeed=vnormalize(<rand(R)*2-1,rand(R)*2-1,rand(R)*2-1>)*rand(R)*10
;

object{Rock_Macro() translate Generate_Path()}

#declare C=C+1;
#end

Hope this helps,

Tim


--
Tim Nikias
Homepage: http://www.digitaltwilight.de/no_lights/index.html
Email: Tim### [at] gmxde


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.