Creating and Warping 3D Text with Away3D 3.6

7 min read

 

The external library, swfvector, is contained in the wumedia package. More information about the swfvector library can be found at http://code.google.com/p/swfvector/. This library was not developed as part of the Away3D engine, but has been integrated since version 2.4 and 3.4, to enable Away3D to provide a way to create and display text 3D objects within the scene.

Embedding fonts

Creating a text 3D object in Away3D requires a source SWF file with an embedded font. To accommodate this, we will create a very simple application using the Fonts class below. This class embeds a single true-type font called Vera Sans from the Vera.ttf file.

When compiled, the resulting SWF file can then be referenced by our Away3D application, allowing the embedded font file to be accessed.

When embedding fonts using the Flex 4 SDK, you may need to set the embedAsCFF property to false, like:

[Embed(mimeType=”application/x-font”, source=”Vera.
ttf”, fontName=”Vera Sans”, embedAsCFF=false)]

 

This is due to the new way fonts can be embedded with the latest versions of the Flex SDK. You can find more information on the embedAsCFF property at http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf6320a-7fea.html.

package
{
import flash.display.Sprite;

public class Fonts extends Sprite
{
[Embed(mimeType=”application/x-font”, source=”Vera.ttf”,
fontName=”Vera Sans”)]
public var VeraSans:Class;
}
}

 

The font used here is Bitstream Vera, which can be freely distributed, and can be obtained from http://www.gnome.org/fonts/. However, not all fonts can be freely redistributed, so be mindful of the copyright or license restrictions that may be imposed by a particular font.

Displaying text in the scene

Text 3D objects are represented by the TextField3D class, from the away3d.primitives package. Creating a text 3D object requires two steps:

  1. Extracting the fonts that were embedded inside a separate SWF file.
  2. Creating a new TextField3D object.

Let’s create an application called FontDemo that creates a 3D textfield and adds it to the scene.

package
{

 

We import the TextField3D class, making it available within our application.

import away3d.primitives.TextField3D;

 

The VectorText class will be used to extract the fonts from the embedded SWF file.

import wumedia.vector.VectorText;

public class FontDemo extends Away3DTemplate
{

 

The Fonts.SWF file was created by compiling the Fonts class above. We want to embed this SWF file as raw data, so we specify the MIME type to be application/octet-stream.

[Embed(source=”Fonts.swf”, mimeType=”application/octet-stream”)]
protected var Fonts:Class;

public function FontDemo()
{
super();
}

protected override function initEngine():void
{
super.initEngine();

 

Before any TextField3D objects can be created we need to extract the fonts from the embedded SWF file. This is done by calling the static extractFonts() function in the VectorText class, and passing a new instance of the embedded SWF file. Because we specified the MIME type of the embedded file to be application/octet-stream, a new instance of the class is created as a ByteArray.

VectorText.extractFont(new Fonts());
}

protected override function initScene():void
{
super.initScene();
this.camera.z = 0;

 

Here we create the new instance of the TextField3D class. The first parameter is the font name, which corresponds to the font name included in the embedded SWF file. The TextField3D constructor also takes an init object, whose parameters are listed in the next table.

var text:TextField3D = new TextField3D(“Vera Sans”,
{
text: “Away3D Essentials”,
align: VectorText.CENTER,
z: 300
}
);
scene.addChild(text);
}
}
}

 

The following table shows you the init object parameters accepted by the TextField3D constructor.

When the application is run, the scene will contain a single 3D object that has been created to spell out the words “Away3D Essentials” and formatted using the supplied font. At this point, the text 3D object can be transformed and interacted with, just like other 3D object.

3D Text materials

You may be aware of applying bitmap materials to the surface of a 3D object according to their UV coordinates. The default UV coordinates defined by a TextField3D object generally do not allow bitmap materials to be applied in a useful manner. However, simple colored materials like WireframeMaterial, WireColorMaterial, and ColorMaterial can be applied to a TextField3D object.

Extruding 3D text

By default, a text 3D object has no depth (although it is visible from both sides). One of the extrusion classes called TextExtrusion can be used to create an additional 3D object that uses the shape of a text 3D object and extends it into a third dimension. When combined, the TextExtrusion and TextField3D objects can be used to create the appearance of a solid block of text. The FontExtrusionDemo class in the following code snippet gives an example of this process:

package
{
import away3d.containers.ObjectContainer3D;
import away3d.extrusions.TextExtrusion;
import away3d.primitives.TextField3D;

import flash.events.Event;

import wumedia.vector.VectorText;

public class FontExtrusionDemo extends Away3DTemplate
{
[Embed(source=”Fonts.swf”, mimeType=”application/octet-stream”)]
protected var Fonts:Class;

 

The TextField3D 3D object and the extrusion 3D object are both added as children of a ObjectContainer3D object, referenced by the container property.

protected var container:ObjectContainer3D;

 

The text property will reference the TextField3D object used to display the 3D text.

protected var text:TextField3D;

 

The extrusion property will reference the TextExtrusion object used to give the 3D text some depth.

protected var extrusion:TextExtrusion;

public function FontExtrusionDemo()
{
super();
}

protected override function initEngine():void
{
super.initEngine();
this.camera.z = 0;
VectorText.extractFont(new Fonts());
}

protected override function initScene():void
{
super.initScene();
text = new TextField3D(“Vera Sans”,
{
text: “Away3D Essentials”,
align: VectorText.CENTER
}
);

 

The TextExtrusion constructor takes a reference to the TextField3D object (or any other Mesh object). It also accepts an init object, which we have used to specify the depth of the 3D text, and to make both sides of the extruded mesh visible.

extrusion = new TextExtrusion(text,
{
depth: 10,
bothsides:true
}
);

 

The ObjectContainer3D object is created, supplying the TextField3D and TextExtrusion 3D objects that were created above as children. The initial position of the ObjectContainer3D object is set to 300 units down the positive end of the Z-axis.

container = new ObjectContainer3D(text, extrusion,
{
z: 300
}
);

 

The container is then added as a child of the scene.

scene.addChild(container);
}

protected override function onEnterFrame(event:Event):void
{
super.onEnterFrame(event);

 

The container is slowly rotated around its Y-axis by modifying the rotationY property in every frame. In previous examples, we have simply incremented the rotation property, without any regard for when the value became larger than 360 degrees. After all, rotating a 3D object by 180 or 540 degrees has the same overall effect. But in this case, we do want to keep the value of the rotationY property between 0 and 360 so we can easily test to see if the rotation is within a given range. To do this, we use the mod (%) operator.

container.rotationY =
(container.rotationY + 1) % 360;

 

Z-sorting issues can rise due to the fact that the TextExtrusion and TextField3D objects are so closely aligned. This issue results in parts of the TextField3D or TextExturude 3D objects showing through where it is obvious that they should be hidden.

To solve this problem, we can use the procedure to force the sorting order of 3D objects. Here we are assigning a positive value to the TextField3D screenZOffset property to force it to be drawn behind the TextExturude object, when the container has been rotated between 90 and 270 degrees around the Y-axis. When the container is rotated like this, the TextField3D object is at the back of the scene. Otherwise, the TextField3D is drawn in front by assigning a negative value to the screenZOffset property.

if (container.rotationY > 90 &&
container.rotationY < 270)
text.screenZOffset = 10;
else
text.screenZOffset = -10;
}
}
}

 

The result of the FontExtrusionDemo application is shown in the following image:

Packt

Share
Published by
Packt

Recent Posts

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago

Gain Practical Expertise with the Latest Edition of Software Architecture with C# 9 and .NET 5

Software architecture is one of the most discussed topics in the software industry today, and…

3 years ago