Join My Conversation twitter
Join My Conversation Rss

Recording Animation

Posted by admin | Posted in Animation | Posted on 10-04-2010

0

In recorded animation, model variables are set from stored values. A few uses are recording human motion (mouse movement) and recording incremental animation. Recording incremental animation would then let you play it back with the kind of control parametric animation gives. You could also get ahold of some motion-capture data and massage it into a form that can be used for playback within Director.

The recording of the animation may be done as part of the program, or done beforehand. If it is done beforehand, the data needs to be saved, most conveniently in a field or text cast member, and then retrieved at run-time. For saving lists in text form, see the Lingo functions string() and value().

Playback of recorded motion is essentially a parametric animation, with the parameter driving an index into the list of recorded values.

This demo allows the user to record a piece of incremental animation, and then play it back with a slider driver. The animation is a combination of collision and general gravity.

on startRecording()
recordList = [:]
repeat with sp in instanceList
recordList[sp] = []
end repeat
state = #recording
end

on record()
repeat with sp in instanceList
recordList[sp].add([#x: sp.x, #y: sp.y])
end repeat
end

on playBack(p) — p:0->1
totalPos = recordList[1].count
index = integer(p * (totalPos – 1) + 1) –index:1->totalPos
repeat with sp in instanceList
pos = recordList[sp][index]
sp.x = pos.x
sp.y = pos.y
end repeat
end

Methods from script “modelManager”

In this demo the recording is done by a script adapted from the modelRate script in Independent Model Rate, and renamed modelManager. The three methods above show how it does recording and playback.

Notice that the variables recorded are the animation model variables, not the sprite properties. This is generally the best way to go, for several reasons:

  • less information to record. For example, in 3D the x, y, and z coordinates are used to set more than three sprite properties. Of course, this means that during playback a rendering algorithm will still be needed.
  • more importantly, at playback you still have control over rendering.

The variables are recorded once each movie frame in this demo, rather than once each model frame. In this demo the model rate is about 20 times the movie rate. If you wanted to do “super slo-mo” playback, you could record the variables based on model frames, and at slow playback you’ll get a smoother motion.

To record the movement of the mouse, use a script that keeps its x and y animation model variables at the mouse location, and pass the script instance to modelManager’s addInstance() method.

Miscellaneous Points
recordList
This is the property list used by modelManager to record the x and y variables of each recorded object. The unusual thing about it is that the keys in the list are object references. recordList associates each object reference with the linear list of recorded position settings for that object.

Usually in sample code the keys are symbols, but the property list can be used to associate values of any data type with each other. This is generally called a hash table, and most likely property lists are implemented in Director using a hash table of some sort.

If recordList is saved in a text cast member, retrieving the list using value() will not recreate object references. To save recordList, use something like sprite numbers for the keys instead of references.

Animation Anomalies
If you watch the animation long enough you’ll notice some interesting anomalies in the behavior of the objects. When I have time I’ll try to pinpoint what is happening. There may or may not be a perfect fix.

Things To Try
Make the playback “instant replay” style by using a time driver instead of a slider to control the playback. You might use a slider to control the speed of the replay.

Popularity: 100% [?]

Collision Using Spring Force

Posted by admin | Posted in Animation, Lingo | Posted on 08-04-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.

Popularity: 52% [?]

The Brain Evolution System

Posted by admin | Posted in Blogging, Marketing | Posted on 07-04-2010

0

For those that are seeking ways to stay alert and mentally tough in today’s demanding world you need to understand how to control your emotions and stay focused on the important tasks that will help you achieve your goals. Through specially created sounds your brainwaves can be influenced to help increase energy, improve memory, and many other great benefits that will improve your overall performance.Through the brainwave meditation system which consists of 6 CD’s it will provide you with the solutions to better focus, higher energy, and help reduce bad habits.

You can find more information and all the science behind the Brain Evolution System can be found at http://www.gobrainev.com. The secret of how this works is based on the frequency of sounds. If you think about the feeling and state that you are in when hearing the crashing sound of waves, the slow patter of rain drops and how calming these various sounds can have on the human spirit and mind. The principles are put into practice and then fine tuned in order to create a unique training system for your brain. You can check out their free trial and see for yourself what this program may be able to offer you or a loved one looking to gain command over their hectic schedule and bring a sense of piece and energy to their lives.

Popularity: 41% [?]

Data Structures and Recursion

Posted by admin | Posted in Animation | Posted on 06-04-2010

1

Intro

Trees

Intro
Data structures store data in a way that reflects some relationship between the data, and is easily useable in a program. Lingo provides some built-in data structures such as lists. This section describes how data structures are created using objects, and some of their common uses in animation. Make sure you’re familiar with the material in Object-Oriented Fundamentals.

The two types of structures covered here are lists and trees, which are both very common and useful. Lingo provides an implementation of lists already; this section shows how to make lists using objects as an intro to making trees.

Uses for lists are fairly obvious. Some uses for trees:

  • 3D world hierarchy
  • working with XML, HTML, etc, which are hierarchical document formats
  • hierarchical displays (such as a file system display)
  • decision trees
  • and many others

Terminology
An object data structure is made of objects that are created from the same script (class). When these objects are assembled into a data structure they are often called nodes of the data structure.

Each node will have properties that are references to other nodes. These object references are what bind the data structure together and are called pointers. How the nodes are arranged using these pointers determines the type of data structure created.

In the diagrams of this section, a square represents a node and an arrow represents a pointer.

Lists
A list is a sequence of nodes. Each node has a pointer to the next node in the list. The nodes in this diagram are created from a script called “listNode”.

To store data in a list, each node has a property or properties that store the data.

The script shown below can be used for the nodes of a list data structure. It has methods for adding a node to the end of the list, and for getting a node at a given position. The property key stores some type of data.

property nextNode
property key

on new(me, _key)
key = _key
return me
end

on addNode(me, _key)
if nextNode = void then
nextNode = script(“listNode”).new(_key)
else
nextNode.addNode(_key)
end if
end

on getNodeAt(me, index)
if index = 1 then return me
if nextNode = void then return void  –index out of range
return nextNode.getNodeAt(index – 1)
end if

script “listNode”

Recursion
It might appear strange that the addNode() and getNodeAt() methods in the listNode script actually call themselves. This programming technique is known as recursion, and is essential for making efficient use of lists and trees.

To understand what is happening, trace the execution from when the method is called on the first node in the list. Each time the method calls itself it moves one node down the list, which is called “traversing” the list. Eventually, the execution reaches what is called a base case at which point there are no further recursive method calls.

In the addNode() method the base case is nextNode = void, which means the end of the list has been reached and the new node can be added.

In the getNodeAt() method there are two base cases. Either the desired node is reached (index = 1) or the end of the list is reached before finding the desired node (nextNode = void). When the getNodeAt() method reaches its base case, the result is returned back through the stack of recursive method calls.

Recursion is useful for working with lists because a list is a recursive data structure. That is, a list is defined in terms of itself. The recursive definition of a list is: “a list is a node followed by a list, or void.”

Try writing recursive methods for the listNode script that:

  • delete the last node in the list
  • delete a node at a given position
  • add a node at a given position
  • return the node whose key matches a given value
  • return the number of nodes in the list
  • return a string that contains the keys of the nodes
  • return the sum of the keys of the nodes (if key is numeric)

Some of these methods are easier to write if each node also has a pointer to the previous node in the list. Such a list is called a “double-linked” list. A listNode script that contains the methods above can be downloaded here. It doesn’t support deleting the first node in the list for the sake of simplicity (how would you do it? Hint: it requires a list implementation using two scripts).

Trees
A tree is also a recursive data structure. It’s similar to a list, except that it can have more than one “next node”. Usually it is drawn vertically to emphasize its heirarchical nature, with next nodes called ‘children’ and the previous node called the ‘parent’.

The top node of the tree is usually called the ‘root’, and is the only node that has no parent. The bottom nodes, which have no children, are called ‘leaves’. Following successive parent pointers from a node will eventually reach the root, and the nodes on this path are the ancestors of the node (not to be confused with the script ancestor property used for inheritance).

Each node in the tree is the root of a sub-tree. A sub-tree can be described as “the sub-tree rooted at this node”.

property parent
property child
property a   –numerical

on new(me, _a)
child = []
a = _a
return me
end

on addChild(me, node)
child.add(node)
node.parent = me
end

on addTo(me, b)
a = a + b
repeat with ch in child
ch.addTo(b)
end repeat
end

on sumTree()
sum = a
repeat with ch in child
sum = sum + ch.sumTree()
end repeat
return sum
end

Sample tree node script that stores a single number

The script above can be used for the nodes of a tree that stores a single number at each node. Like the methods that traverse the list data structure, a recursive method can be written to traverse and process a tree data structure. The example methods addTo() and sumTree() both traverse the tree.

n.addTo(num) increments by num the value in each node in the sub-tree rooted at n. If n is the root of the tree, all nodes in the tree are incremented.

n.sumTree() returns the sum of the values stored in the nodes in the sub-tree rooted at n. If n is the root of the tree, the sum of all nodes in the tree is returned.

These recursive methods visit the nodes in the tree in this order:

This is called a ‘depth-first’ traversal since it travels to the bottom of the tree first, rather than processing one level before going to the next.

Here is another tree node script that shows some more recursive tree methods

Popularity: 97% [?]