Scripting
3D in Flash
by
senocular
Solid Pyramids
This example has two fully solid pyramids.
One uses the visibility function for backface
culling and the other uses separate movieclips
for faces and uses swapDepths for each of those
clips to properly arrange them. Those depths are
based on an average z of the 3 points making up
each face.
[
two drawn solid pyramids ]
Steps to Create Animation
- This
example starts off similar to the previous only
here, there are 2 scenes, one for each of the
pyramids which are to operate independent of
each other. The focalLength will be used in
both, so that can remain a single variable.
- Following
that, the visibility function can be added.
This will be used in the first pyramid for backface
culling taking three of the points making up
a face in the pyramid and determining visibility
of that face based on slope and position of
each point in relation to each other. The second
pyramid will not use this function in favor
of having each face as a movieclip and using
swapDepths to properly overlap each face.
- Next
are the make point functions. This example will
actually drop the make2DPoint function all together.
One of the reasons is that for the second pyramid
using swapDepths to arrange faces, a depth or
z value will be needed for each converted 2D
point to determine the depth of the face. Secondly,
a 2D point is just a 3D point minus one property,
z, so why not just drop the 2D point if the
3D point can be used instead (which it needs
to be to get that z value to figure for depth).
The make3DPoint function itself has not changed.
- Now
for the Transform3DPointsTo2DPoints work horse.
The only change here is the using of the make3DPoint
for the 2D points in the transformed array.
Technically the point will still be 2D, at least
in its x and y values, but the z value will
be the 3D point which is retained for determining
depths etc.
- And
now the pyramid can be defined. A pyramid is
fairly easy - only three points.
- Because
there are two scenes, 2 separate onEnterFrame
functions will be defined for both, each using
a separate technique of creating a filled pyramid.
The first will be the one with backface culling
using the isVisibleBetween function defined
earlier. The isVisibleBetween function is used
to determine, given 3 points, whether the face
made by those points is visible or not. If its
not, then you shouldn't bother drawing the face.
So, each time a face is to be drawn between
any three points (which happens four times for
each face every frame), isVisibleBetween needs
to be called for those points in an if check
to make sure the drawing should proceed. If
not, on to the next face. An added mouseIsDown
variable is used to disable the beginFill function
if the mouse is being pressed (Key.isDown(1)
checks for the left mouse button being pressed
if you weren't already aware of that). Note
that everything is being drawn directly in the
current scene movieclip.
- This
second pyramid uses separate movieclips to draw
its faces and each face is then swapped to an
appropriate depth to keep overlapping appropriate
and the pyramid appear solid. Each clip has
its own specific face drawn within it every
frame (whether its technically visible or not)
and an average values of the z values for each
point is in that face is used to swap each clip
to the right depth keeping those clips that
need to be on top, on top. When the mouse is
pressed, for this pyramid, you can see the lines
which were previously invisible or hidden by
movieclip(s) on top whereas in the other pyramid
they are not seen since they aren't even drawn.
Of course, before implementing the function,
the clips will need to be created for each face.
|
SUGGESTION:
Tips for Speed Optimization |
Flash
isn't fast. Remember that. Flash has
a lot to put up with in terms of showing
things on the screen as well as calculating
everything it needs to at the request
of your Actionscript. Because the Flash
player is meant to be a light and lean
plugin, there can only be so much done
to enhance its speed. With that in mind,
you will need to keep your actionscript
as proficient and efficient as you can
when dealing with a lot of operations
that need to be calculated every frame
- as is the case with 3D in Flash. Here
are some tips you can apply to your
code to help speed things up. Remember,
every little bit counts:
- Shorter variable
names run faster (be careful not
to sacrifice too much clarity of
your code for this slight speed
boost). myLongVariableName
would perform slow in comparison
to myV. You can assign
a long variable to a shorter variable
name if its going to be accessed
repeatedly.
- Bracket or 'associative
array' syntax for referencing properties
in an object or array can be much
slower than normal dot syntax property
referencing. For example, myObject["property"]
is much slower than myObject.property.
Because arrays use this syntax,
inherently accessing array values
is quite slow in comparison to normal
object properties. If you can use
an object instead of an array, do
so. You can assign an bracket-accessed
variable to a single short variable
name if its going to be accessed
repeatedly.
- Local variables
in function calls created with the
var keyword are faster than other
variables. Be sure not to reinitialize
var variables within a loop block,
however, as that would not be as
efficient. Instead, declare any
local variables used in loops outside
the loop first.
- Function calls
on the whole can take time to process.
The fewer function calls you make
the less overhead you have in processing
your script.
- Along those same
lines, don't process things more
than once if you can just reuse
the result of the first calculation.
An example being the Math.sin()
and Math.cos() calls. They only
needed to be called a total of 3
times each for each frame of animation
in a 3D environment. There's no
need to call them repeatedly with
the same values if they don't need
to be. This not only applies to
function calls but any other operation
even if as simple as an addition
of two numbers. Save that result
in a variable and reuse it again
later instead of re-calculating.
- For..in loops can
be faster than normal for loops.
You may have to, however, when using
a for..in loop, use checks to make
sure you are looping through the
correct properties which cause a
script to run slower than if it
was performed with a normal for
loop. Also, for..in loops are not
faster when used with very large
arrays.
- Generally subtraction
is slightly faster than
addition. Because of this, a way
to speed up addition would be to
subtract the negative of what you're
adding. In other words, x = y+1;
becomes x = y - (-1);
- Pre-increment can
also be slightly faster
than post-increment. --x; over x--;
Be wary of their uses in loops,
however, as each will be treated
differently.
- One of the biggest
boosts in speed, sadly, is through
using deprecated functions such
as random over Math.random and things
like tellTarget instead of with.
tellTarget can be as much as 25
times faster than with, though since
these methods are technically no
longer supported, you'll have to
be cautious how much you use them.
It might not be long where they
will become obsolete and ineffective.
|
|
Advantages in Separated Faces
Using the separate movieclips for each face opens
up some possibilities in terms of interaction
with those faces. As movieclips, each face is
completely separate from the other faces in the
shape. Being that they are all their own individual
clips, you can assign clip specific actions to
certain and single faces. For example, a single
face can act as a button. A 3D object with interactive
button-faces? Exciting, isn't it?
|