« SCORM & Director | Main | My interview on the Director Podcast »
March 03, 2006
3D Model Resources: Extruding Vector Shapes
At long last I'm back with another Friday dose of undocumented fun in Director and the Shockwave Player. This particular undocumented technique is one that allows you to create 3D model resources by extruding vector shape cast members. This is a bit of an involved process so it's a longer read than the other items I've posted, but I think it's worth it if you don't know of this already.
Built into all versions of Director and Shockwave since v8.5 is the capability to extrude text strings into model resources within a 3D cast member. Extruding of strings is really just an excercise in vector shape extrusion where the font and characters used determine the shape of the outline that is extruded. There is an undocumented property of #extruder model resource objects (those created via the extrude3d text cast member method) that allows you to update the vertex list of an extruded model resource to any desired shape. When you update the model resource's vertex list, all of the previously held properties relating to the extrusion are maintained (bevelDepth, bevelType, displayFace, smoothness, tunnelDepth). You can set these either before or after the extrusion and/or vertex list replacement.
There are in fact two means by which you can update the vertex list, one is to simply set the entire list equal to a new list, the second is to manually draw the needed outlines by using further undocumented commands. First I'll discuss how to go about getting an #extruder model resource, then I'll talk about the capability to simply set the resource's vertex list to a new value and finally I'll discuss how to go about drawing the outline manually.
Getting an #extruder model resource
We must create an #extruder model resource object, this is achieved by using the extrude3d text member method:
-- create a text cast member
tTextMember = new(#text)
-- initialize the member with any string
tTextMember.text = "a"
-- extrude the text member's string into a 3D cast member
tExtruderResource = textMember.extrude3d(member("3D")
The font and display settings of the text member are of no importance being as they only affect the outline to be extruded and we'll be providing our own outlines later.
Replacing the resource's vertex list
Now that we have an #extruder model resource we can simply push a new vertex list onto the resource via the resource's undocumented vertexList property. For example:
-- grab vertex list of vector shape cast member
tList = member("vector shape").vertexList
-- update model resource
tExtruderResource.vertexList = tList
I've experimented with this a bit but not extensively. I recall warnings that the winding order of vector shapes can be/is sometimes in reverse order resulting in objects not rendering correctly (their insides are pointing out). This can be repaired by walking your vector shape's vertex list and multiple all y-coordinate values by -1.
Drawing the new outlines manually
This technique is a bit more involved and is something that I've only tried once with minimal success (a portion of my troubles was most certainly due to errors on my part though). Once you've created an #extruder model resource you can then draw your outlines using the following undocumented commands: startCompositePath, startCompositeElement, startPath, moveTo, curveTo,lineTo, endPath, endCompositeElement, and endCompositePath. Here is a quick and rough definition of each command:
startCompositePath / endCompositePath
syntax: extruderResourceRef.startCompositePath()
syntax: extruderResourceRef.endCompositePath()
These commands start and end the creation of a composite path (a string is an example of a composite path); once you've created your #extruder resource, starting a composite path is the first thing you'll do and ending that composite path the last thing you'll do.
startCompositeElement / endCompositeElement
syntax: extruderResourceRef.startCompositeElement()
syntax: extruderResourceRef.endCompositeElement( point )
These commands start and end the creation of a composite element (a character is an example of a composite element); you must first create a composite path before creating composite elements; end a composite element to begin working on the next element. When using the endCompositeElement command you must provide a point value that offsets to the next composite element (character) to draw.
startPath / endPath
syntax: extruderResourceRef.startPath()
syntax: extruderResourceRef.endPath()
These commands start and end the creation of a path (the dot in an "i" is one path, the vertical bar another); you must first create a composite element before creating a path; end one path in order to be able to start another.
moveTo
syntax: extruderResourceRef.moveTo( point,#boolean )
After you have begun a path using the startPath command you can set the point at which you would like your new path to begin by using this command. The moveTo command also contains a second parameter in which you specify if the curve about to be drawn is on the inside (the center of an o) or the outisde (the outer ring of an o). Passing a value of TRUE results in an outside path while a value of FALSE results in an inside path.
curveTo
syntax: extruderResourceRef.curveTo( controlPt1,controlPt2,point )
After you have begun a path using the startPath command you can draw your next vertex by specifying its position and control hadles using this command. All parameters are #point values.
lineTo
syntax: extruderResourceRef.lineTo( point )
After you have begun a path using the startPath command you can draw your next vertex specifying just its position using this command. The parameter provided is a #point value.
Here is some code that you can copy and paste right into your message window in order to use the above commands to draw and extrude a vector box shape:
-- create text member
tTxt = new(#text)
-- member must have a string in order to extrude
tTxt.text = "a"
-- create 3D member
tMem = new(#shockwave3D)
-- extrude text member
tMR= tTxt.extrude3d(tMem)
-- create model using the #extruder resource
tM = tMem.newmodel("a",tMr)
-- place member on stage, verify that you see an
-- extruded letter "a", when done *remove*the*
-- sprite*from*the*stage*; I'll explain later
-- start the composite path
tMr.startCompositePath()
-- start a composite element
tMr.startCompositeElement()
-- start a path
tMr.startPath()
-- move initial vertex into place
tMr.moveto(point(0,0),TRUE)
-- make a line connection with second vertex
tMr.lineTo(point(25,25))
-- make a line connection with third vertex
tMr.lineTo(point(0,50))
-- make a line connection with the fourth vertex
tMr.lineTo(point(-25,25))
-- connect a line back to our initial point
tMr.lineTo(point(0,0))
-- end the path
tMr.endPath()
-- end the composite element
tMr.endCompositeElement(point(0,0))
-- end the composite path
tMr.endcompositepath()
-- place member back on stage, you should now see an
-- extruded square
Stability Warning
It should be noted that upon being told of this capability I was also sternly warned that I should not perform any of the above drawing routines while the cast member is actually being rendered. I haven't tested that rule (meaning I've always done this with the member not being rendered), do so at your own risk/benefit.
Disclaimer: I make no guarantees regarding validity or usefullness of the information contained in this post. This feature was left as undocumented, and therefore unsupported on purpose, it either wasn't fully developed and/or it wasn't fully tested. I suggest that you utilize this technique in experimental movies due to the potential risks involved. There is no guarantee that this undocumented feature will survive from release to release. Use this technique at your own risk!
Posted by thiggins at March 3, 2006 02:14 PM