Join My Conversation twitter
Join My Conversation Rss

Independent Model Rate

Posted by admin | Posted in Uncategorized | Posted on 14-09-2011

0

Independent Model Rate

This section describes a method of programming incremental animation that gives two advantages:

  • frame-rate independence for incremental animation
  • high model rates for normal (<100 fps) movie frame rates. High model rates make some incremental algorithms function more accurately.

This demo gives the Collision Using Spring Force demo an independent model rate.

The Model
The variables used in an incremental animation—position, velocity, etc of a set of objects—along with the algorithm that makes them interact is called a model. At any point in time the variables store the state of the model.

The model is separate from what appears on screen, which is merely a visual representation of the state of the model. Usually they are so closely related that they might seem like the same thing. However, the model can execute just fine without ever showing a representation of it on screen. The position and velocity variables would still go through their various values, depending on the model algorithm, even if the sprite properties are never set accordingly.

The act of creating a visual representation of a model is called rendering. To set sprite and cast member properties based on a model is a form of rendering.

Model Rate
Each time a model algorithm is executed, updating the state of the model, it is one iteration, or step. I’ll call this a “model frame” in keeping with Director terminology. So the number of model frames per second is the “model frame rate” or just “model rate”.

So far in the incremental animation demos, the model rate has been tied to the movie frame rate because the model algorithm was executed once per movie frame, in the exitframe handler.

In this demo those two rates are separated. The script below shows the form of the standard behavior script with a slight modification made to provide the rate separation.

global modelRateObj

property sp
– and other properties declared

on beginsprite(me)
sp = sprite(me.spritenum)
– and other variables initialized

modelRateObj.addInstance(me)
end

on modelFrame(me)
– perform incremental animation algorithm
end

on exitframe()
sp.loch = x
sp.locv = y
— and other sprite properties set
end

Sprite behavior showing separation of movie and model rates

The primary difference is that the model algorithm has been moved out of the exitframe handler and into a ‘modelFrame’ handler. Now the model algorithm can be executed independent of the frame rate of the movie. The only statements left in the exitframe handler are those that render the model.

All that is left to do is call the modelFrame handler of each object however many times per second is desired. For correct function of the collision model it is necessary that the objects’ modelFrame handlers are called in step with each other.

In this demo this is done by a script I’ve named modelRate, which is instantiated when the movie starts.

property modelFPS
property millis
property instanceList

on new(me, mfps)
instanceList = []
modelFPS = mfps
millis = the milliseconds
(the actorlist).append(me)
return me
end

on stepframe()
elapsed = the milliseconds – millis
mframes = integer(modelFPS * (elapsed / 1000.0))
doModelFrames(mframes)
if modelFPS > 0 then
millis = millis + (mframes / float(modelFPS)) * 1000
end if
end

on doModelFrames(mframes)
repeat with mf = 1 to mframes
repeat with instance in instanceList
instance.modelFrame()
end repeat
end repeat
end

on addInstance(me, inst)
instanceList.append(inst)
end

script “modelRate” – an explanation of “the actorlist” is given here

modelRate maintains a list of script instances, and it calls the modelFrame handler of those instances so many times per second. It is the responsibility of each object in the model to register itself with modelRate by passing a reference to itself to modelRate’s addInstance handler. This was shown in the behavior script above, with the statement modelRateObj.addInstance(me).

When modelRate is instantiated, the desired model frame rate is passed to the new() handler. After instantiation, the model frame rate is adjusted by changing modelRate’s modelFPS property.

The function of this modelRate object is very similar to Director’s use of
the actorlist, except it calls modelFrame() so many times per second where stepframe() is called once per frame. modelRate could be written to be based on the frame rate and call modelFrame() so many times per movie frame.

One point about the line millis = millis + (mframes / float(modelFPS)) * 1000. Usually this is just a reset of millis with millis = the milliseconds. The way it is reset here compensates for the rounding done to get mframes, so the resulting model rate is correct.

Biased Slider Drivers
This part is related to the material in the parametric animation section.

The sliders in this demo are programmed as parametric animation drivers. The parameters they provide are then biased, using a bias-out function. Notice that when the model rate slider sits at the middle of its range its value is 500, even though the slider goes from 0 to 2000. By biasing the parameter, finer adjustments can be made at the lower end of the range (at the expense of adjustment at the high end). For finer adjustment at the higher end, a bias-in function would be used.

There are two scripts attached to each of the sliders. One provides the driver function p(), and the standard slider driver code. The other script gets the value returned by p() and uses it to set properties and variables specific to this demo. This maintains the modularity of the scripts.

Model/Display separation

Posted by admin | Posted in Uncategorized | Posted on 05-04-2011

0

Model/Display Separation

The Model
The animation model is the set of variables, such as position, velocity, etc, that store the state of the animation along with the algorithm that makes their values change. It is a mathematical model, consisting of numbers and calculations with them.

The animation model is really separate from what appears on screen, which is merely a visual representation of the model. They are often closely related so that they seem like the same thing. However, the model can function without ever showing a representation of it on screen.

Separating the model from the display means two things:

  • First, it means the model uses only its own variables (like x, xVelo, xAccel, etc) and doesn’t use display properties (like loch and locv, stage width/height, etc). If these properties are needed, variables are initialized to them and then the variables are used.
  • Second, it means writing code that renders the model. This is often done by simply setting sprite properties equal to the model variables, but there is much more that can be done at this step.

Rendering
Creating a visual representation of a mathematical model is called rendering. The diagram below shows the usual way to render an animation in Director. As a logical step, rendering includes the calculations you make to set sprite and cast member properties, as well as Director’s drawing of the screen based on them:

In the first render step, sprite properties are set based on the variables of the animation model. Often this is just setting the sprite properties equal to the model variables. But with an algorithm at this step you can scale, rotate, apply perspective, distort, etc, the animation.

In the second render step, Director uses sprite and member properties to set the rgb value of each pixel of the stage.

This demo is a revisit of Inventing a Force, but separates the model from the display and gives the user control over the first rendering step.

Model/display separationsource movie

The important thing to note is that the animation model is not affected by adjusting the sliders. Only the rendering is affected.

Property lists are used as vectors in the demo. The method of rotating the vectors is covered in Incremental Rotation (coming).

Coordinate System
By separating the model, you can use whatever kind of coordinate system you’d like. If you prefer to have your animation model centered around the origin (0,0) you can do that, and part of the rendering will be to shift the coordinates to screen coordinates. Or you can use a 3D coordinate system or polar coordinate system, and render from those.

Other Ways to Render in Director
There is more than one way to render an animation model:

  • set sprite properties, as done in this demo
  • use imaging lingo to render to an image object
  • set Shockwave 3D properties
  • set vector cast member properties
  • text-based animation (hey, it would work!)

And there are probably others as well. If you wanted you could render the same animation model in all these ways in the same program.

Other Examples
Case Study: Space Viewport
Independent Model Rate
All of the 3D quad demos

Collision Using Spring Force

Posted by admin | Posted in Uncategorized | Posted on 23-05-2010

0

Collision Using Spring Force

When two objects rebound after colliding with each other, it is due to a spring force, even though it may not look like it. When two billiard balls collide, the compression of the ball is limited to a miniscule fraction of its width but it still happens.

Using a spring force requires higher model rates to realistically collide faster, harder objects. The fps display in the demo shows the actual frame rate. The movie itself is set to 999 fps. On a 1.3 GHz P3 it averages about 980 actual fps.

repeat with s = 1 to 4
if s <> me.spritenum then
spOther = sprite(s)

–distance components
distX = (spOther.x) – x
distY = (spOther.y) – y

–pythagorean theorem to get distance
dist = sqrt(power(distX,2) + power(distY,2))

–spring force
xSpring = 0
ySpring = 0
minDist = (sp.width + spOther.width) / 2.0 - 10
if dist < minDist then
springF = (minDist – dist) * .02
xSpring = springF * -(distX/dist)
ySpring = springF * -(distY/dist)
end if

xTotalForce = xTotalForce + xSpring
yTotalForce = yTotalForce + ySpring
end if
end repeat

The algorithm is almost identical to general gravity, so only the repeat loop is shown. Instead of calculating gravity, it calculates spring force. Spring force only acts when the objects are within a certain distance of each other, expressed as dist < minDist.

The magnitude of the spring force is given by minDist – dist. This is the restPosition – position equation from the Spring Forces section. Scaling by .02 puts the force into proportion with other values in the animation. It can be considered the stiffness of the object, the higher it is the stiffer the object.

This demo gives each object a mass, and uses the mass in the
accel = force / mass equation. The behavior of the large object shows how mass affects acceleration. When two objects collide, each experiences the same amount of force, acting in opposite directions. This force translates into a smaller acceleration for more massive objects.

Mass can be set however you’d like. In this demo it is set to the cube of the sprite width, which would roughly correspond to its mass if it was a
3-dimensional sphere.

The type of collision modelled in this demo is for round objects with no friction between them. Friction or non-round shape would cause part of the energy in the collision to go into rotational velocity, making the objects spin.

For comments on the rest of the script, see General Gravity.