Join My Conversation twitter
Join My Conversation Rss

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.

Collision using spring forcesource movie

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: 45% [?]

The Quad Property

Posted by admin | Posted in Lingo | Posted on 20-02-2010

0

The sprite.quad property is a list of four points that specify the screen coordinates of the corners of a sprite. If the quad property is set in Lingo, Director will distort the sprite accordingly. This allows the rendering of 3D rotation of a sprite.

Drag on the screen to spin the object
Quad propertysource movie

property sp
property verts
property trans
property rotVelo

on beginsprite(me)
sp = sprite(me.spritenum)
verts = []
verts[1] = vector(-1,1,0)
verts[2] = vector(1,1,0)
verts[3] = vector(1,-1,0)
verts[4] = vector(-1,-1,0)
trans = transform()
trans.scale = vector(150,150,1)
rotVelo = vector(.3,.2,0)
end

on exitframe()
modelFrame()
render()
end

on modelFrame()
trans.rotate(rotVelo)
end

on render()
eyez = 500
ptList = []
repeat with v = 1 to 4
vec = trans * verts[v]
persp = eyez / (vec.z + eyez)
pt = point(vec.x * persp, vec.y * persp) + stageCenter
ptList.add(pt)
end repeat
sp.quad = ptList
end

The Model
The animation model in this demo consists of four vectors, a transform, and a rotational velocity. The four vectors specify the corners of the object, and are analogous to a “model resource”. The transform is used to specify the scale, translation, and rotation of the object. Each model frame, the transform is rotated by a vector that specifies rotational velocity.

The model could have been stored in four vectors that specify 3D world coordinates, without using a transform. But keeping the resource information and transform separate makes transforming easier, and makes it easier to animate the corners with respect to each other.

•How would you change the “registration point” of the plane?

Rendering
Multiplying each resource vector by the transform gives the 3D world coordinates of the corners. The perspective equation is then used to map the 3D points to 2D. The 2D points are put in a list which is used to set the sprite’s quad property. The order of the points is clockwise from upper-left for right side up facing the viewer, which is the reason for the order of the resource vectors.

The next section shows how to combine quads to make 3D objects.

Popularity: 93% [?]

Space Viewport 2.0

Posted by admin | Posted in Lingo, Marketing | Posted on 28-01-2010

0

Case Study: Space Viewport 2.0

Related Topics:
Space Viewport
Perspective & Other Depth Cues
Data Structures and Recursion

View controls:
Drag in viewport to pan
Drag on ‘radar’ to pan
Alt-drag in viewport to zoom
Click ‘follow’ to follow ship
Ship controls:
left/right arrows to turn
ctrl to thrust

Space Viewport 2.0source movie

This demo builds on the first version by giving universe elements a depth and rendering with some depth cues, and also storing the universe model in a tree rather than a list.

Depth & Perspective
The field of action is still two dimensional, but adding depth makes the visuals more interesting. It’s pretty simple to do. Each element is given a z coordinate which is used for perspective and for blendlevel (haze) and locz (z-axis blocking).

Notice how the method uniToView() which maps universe to screen coordinates now makes use of the perspective value. First the offset from the camera is found (vec – camVec), then perspective is applied, then zoom and shifting:

on uniToView(vec)
vec = (vec – camVec) * persp
loch = vec.x * zoomLevel + viewRect.left + viewRect.width/2
locv = vec.y * zoomLevel + viewRect.top + viewRect.height/2
return point(loch, locv)
end

Tree Structure for the Model
Instead of being stored in a list, the objects of the universe are now stored as a tree. The universe object is the tree root, and each object’s position is relative to its parent. The circling planets show how the tree structure simplifies the programming—the planet script doesn’t need to take into account how the sun fits into the rest of the scene. For more on using a tree and transforms in animation see 3D World and the other 3D quad demos.

Migrating to a tree structure was made much easier by inheritance. Simply making the treeNode script the ancestor of universeElement gave all the model objects the properties and methods of a tree node.

This demo is a relatively rare example of the use in Lingo of a series of inheritance, where a script’s ancestor itself has an ancestor. For example, ship inherits universeElement which inherits treeNode. Does it make a difference if universeElement and treeNode are reversed in the order? It wouldn’t to the ship script, but there are reasons to arrange it the way it is. Abstractly, according to the “is a” relationship of inheritance, universeElement is a treeNode but treeNode is not a universeElement. Practically, if you wanted a node just for grouping in the model you can now just use a universeElement object (because it inherits from treeNode).

Popularity: 89% [?]