how to create your own primitives - like a plane with rounded edges?

Software: Away3D 4.x

Avatar
FlyOn, Jr. Member
Posted: 06 January 2012 03:56 PM   Total Posts: 36

Hi,

I would like to create some more generic shapes ... for example a plane with rounded edges ... I’ve looked at the existing primitives, but when I follow the code and print the genereated data I’m just not sure what the generate normals, tangents and indices mean ...

I guess this is where I just have to dive deeper in 3d graphics programming…

any tips as how to procede? where to learn?

tnx!

   

John Brookes, Moderator
Posted: 06 January 2012 04:51 PM   Total Posts: 732   [ # 1 ]

This basic traingle may help you see whats going on.

package away3d.primitives
{
 import away3d
.arcane;
 
import away3d.core.base.SubGeometry;
 
import away3d.materials.MaterialBase;
 
import flash.geom.Vector3D;

 use namespace 
arcane;
 
 public class 
Triangle extends PrimitiveBase
  {

  
private var _v0:Vector3D;
  private var 
_v1:Vector3D;
  private var 
_v2:Vector3D;
  private var 
_uv0:Vector3D;
  private var 
_uv1:Vector3D;
  private var 
_uv2:Vector3D;

  
// Define vertices in a clockwise manner.
  
public function Triangle(material:MaterialBasev0:Vector3Dv1:Vector3Dv2:Vector3Duv0:Vector3D nulluv1:Vector3D nulluv2:Vector3D null)
  
{
   super
(material);

   
_v0 v0;
   
_v1 v1;
   
_v2 v2;
   
_uv0 uv0;
   
_uv1 uv1;
   
_uv2 uv2;
  
}

  override 
protected function buildGeometry(target:SubGeometry):void
  {
   
var rawVertices:Vector.<Number> = Vector.<Number>([_v0.x_v0.y_v0.z_v1.x_v1.y_v1.z_v2.x_v2.y_v2.z]);
   var 
rawIndices:Vector.<uint> = Vector.<uint>([012]);

   var 
d0:Vector3D _v1.subtract(_v0);
   var 
d1:Vector3D _v2.subtract(_v0);
   var 
rawTangents:Vector.<Number> = Vector.<Number>([000]);

   var 
normal:Vector3D d0.crossProduct(d1);
   
normal.normalize();
  
// trace("add triangle,normals", normal.x, normal.y, normal.z);
   
var rawNormals:Vector.<Number> = Vector.<Number>([normal.xnormal.ynormal.znormal.xnormal.ynormal.znormal.xnormal.ynormal.z]);

   
target.updateVertexData(rawVertices);
   
target.updateVertexNormalData(rawNormals);
   
target.updateVertexTangentData(rawTangents);
   
target.updateIndexData(rawIndices);
  
}

  override 
protected function buildUVs(target:SubGeometry):void
  {
   
if(_uv0 && _uv1 && _uv2)
    var 
rawUvData:Vector.<Number> = Vector.<Number>([_uv0.x_uv0.y_uv1.x_uv1.y_uv2.x_uv2.y]);
  
}
 }
   

Avatar
FlyOn, Jr. Member
Posted: 07 January 2012 11:06 AM   Total Posts: 36   [ # 2 ]

Tnx John, that is a good start!

But I still don’t understand from this what for example tangents are, what they represent and how to build them for more complex objects ... (cause I guess they’re not always 0) ... do you perhaps know a good place to learn?

   

John Brookes, Moderator
Posted: 08 January 2012 03:48 PM   Total Posts: 732   [ # 3 ]

“guess they’re not always 0”
That should be 1,0,0

Also buildUvs should be something like
var rawUvData:Vector.<Number>
if(_uv0 && _uv1 && _uv2)
  rawUvData = Vector.<Number>([_uv0.x, _uv0.y, _uv1.x, _uv1.y, _uv2.x, _uv2.y]);
else
rawUvData = Vector.<Number>([0, 0, 0, 1, 1, 1]);

target.updateUVData(rawUvData);

Sorry, I blame Li smile)
http://code.google.com/p/litools/source/browse/trunk/com/li/away3d/primitives/Triangle.as

How do you caluclate them?
If your not using bump mapping, you dont need them (I think, not sure if anything else needs them).

The easy way, would be to not bother and use
target.autoDeriveVertexTangents = true;
instead of
target.updateVertexTangentData(vertexTangents);

or
myMesh.subGeometries[0].autoDeriveVertexTangents = true;
after you create the mesh.

Same with normals
target.autoDeriveVertexNormals = true;


If you were doing a plane with rounded corners then the tangents would still be 1,0,0
Trying to think of a better way to say this but..
tangents basically point in the same direction as the u of the UV space blaa blaa blaa and averaged with any shared vertices.
try that google thang wink Or work out what happens in subGeometry.as updateVertexTangents()


As for indices.
Little example with a plane.
If you trace out the vertices for the plane.

var plane:Plane = new Plane(new ColorMaterial(0xff0000));
scene.addChild(plane);

trace(plane.geometry.subGeometries[0].vertexData);
//-50,0,-50, 50,0,-50, -50,0,50 ,50,0,50

You only seem to get 4 vertices, you would expect there would be 6 ( 2 triangles), something like
-50, 0, -50,  -50, 0, 50,  50, 0, 50,  -50, 0, -50,  50, 0, 50,  50, 0, -50
Thats because the adjacent edge of the two triangles are sharing the same vertice positions.


Tracing out the indices
trace(plane.geometry.subGeometries[0].indexData);
//0,2,3,0,3,1
yay we got six of something
Notice 0 and 3 appear twice, they are the shared ones.

Indices give you the index position of the vertices,Uvs,normals and tangents.

eg

var index:Vector.<uint> = plane.geometry.subGeometries[0].indexData;
var 
vertex:Vector.<Number> = plane.geometry.subGeometries[0].vertexData;
var 
tangent:Vector.<Number> = plane.geometry.subGeometries[0].vertexTangentData
var normal:Vector.<Number> = plane.geometry.subGeometries[0].vertexNormalData;
var 
uv:Vector.<Number> = plane.geometry.subGeometries[0].UVData;
var 
ind:uint 0
for ( var i:uint 0index.lengthi++)
{
 ind 
index[i]*3;
 
trace(vertex[ind] vertex[ind+1]vertex[ind 2]);
 
//trace(normal[ind] , normal[ind+1], normal[ind + 2]);
 //trace(tangent[ind], tangent[ind + 1], tangent[ind + 2]);
 
 /*UVs only 2 components
 * ind = index[i] * 2;
 * trace(uv[ind] , uv[ind + 1]);
*/

A mesh can be made with shared vertices,normals etc or with unique ones or a mixture of both.
The cube uses both, shared vertices tangents and normals for each side unique for each edge of the cube.
Basically unique will give a harder edge under lights as the normals for each vertex can be slightly different.

//add a light to your mesh then try this

//raise the Y component of the first vertice by 50 (this is a shared one)
plane.geometry.subGeometries[0].vertexData[1] += 50;
plane.geometry.subGeometries[0].updateVertexData(plane.geometry.subGeometries[0].vertexData)

render and you see the edge isnt very hard under the lights thats the shared normals

now add

//makes all vertices normals tangents unique
Explode.apply(plane, false);

You will see a harder edge under the light.


Another thing that may help
look at
MeshDebugTest in the examples to see normals/tangents etc and play about.

 

Blaa blaa blaa lots of other stuff
erm google wink

   

Avatar
FlyOn, Jr. Member
Posted: 08 January 2012 04:48 PM   Total Posts: 36   [ # 4 ]

wooooaahh, tnx so much for writing that all out, this is reallllly helpful!
now I know much better where and how to dive into this stuff smile

I hope to post a success story soon!

   

RiaanWest, Newbie
Posted: 05 March 2012 03:19 PM   Total Posts: 3   [ # 5 ]

Wow JohnBrookes, thanks for your reply. Just learned a bucket-load! grin

   
   
‹‹ Example .FLAs

X

Away3D Forum

Member Login

Username

Password

Remember_me



X