It has not as many features as a real matrix extrude but it looks smooth and organic. It is all calculated at runtime using a Sphere object of Papervision3D and then extruding some faces of it five times based on their face-normal rotated using the Matrix3D class.





Very nice! any chance to see the source code of it?
thank u
A.
Somewhere in the history of the PV3D mailing list I posted codes how you can extrude a face. This one is like a simple extrude but you do more steps and shift the face normals around.
ok :) do u have any link about that code needed to extrude a face?
thank u!
Has been done with an _old_ version of PV3D. I also had a function to clone the geometry object of a DisplayObject3D involved there somewhere.
class Extrude
{
public function Extrude( geometry: GeometryObject3D, faces: Array, direction: Number3D )
{
var cloneVertices: Array = new Array;
var usedInFaces: Dictionary = new Dictionary;
var m: int;
var n: int;
var o: int;
var i: int;
var j: int;
var k: int;
var vertex: Vertex3D;
n = faces.length;
//-- LOOP THROUGH FACES
//-- CLONE ALL VERTICES THAT ARE INVOLVED
//-- DO NOT CREATE DUPLICATES!
for ( i = 0; i < n; i )
{
var face: Face3D = faces[ i ];
var vertices: Array = face.vertices;
m = vertices.length;
for ( j = 0; j < m; j )
{
vertex = vertices[ j ];
if ( !inArray( cloneVertices, vertex ) )
cloneVertices.push( [ vertex, null ] );
if ( usedInFaces[ vertex ] == null )
usedInFaces[ vertex ] = 1;
else
usedInFaces[ vertex ] ;
}
}
n = cloneVertices.length;
//-- LOOP THROUGH NEW VERTICES
//-- CLONE VERTEX AND MOVE BY DIRECTION
for ( i = 0; i < n; i )
{
vertex = cloneVertex( ( cloneVertices[ i ] as Array )[ int( 0 ) ] );
vertex.x = direction.x;
vertex.y = direction.y;
vertex.z = direction.z;
( cloneVertices[ i ] as Array )[ int( 1 ) ] = vertex
geometry.vertices.push( vertex );
}
n = faces.length;
o = cloneVertices.length;
var cloned: Array;
//-- LOOP THROUGH FACES AGAIN
//-- FIND CLONED VERTICES THAT BELONG TO OLD FACE AND CREATE NEW ONE
//-- CREATE NEW FACE AS WELL IF VERTEX IS NOT ACCESSED BY MORE THAN 1 FACE
for ( i = 0; i < n; i )
{
face = faces[ i ];
vertices = face.vertices;
cloned = new Array;
m = vertices.length;
for ( j = 0; j < m; j )
{
vertex = vertices[ j ];
for ( k = 0; k < o; k )
if ( ( cloneVertices[ k ] as Array )[ int( 0 ) ] == vertex )
cloned.push( ( cloneVertices[ k ] as Array )[ int( 1 ) ] );
}
geometry.faces.push( new Face3D( cloned ) );
var jp1: int;
for ( j = 0; j < m; j )
{
jp1 = j 1;
if ( jp1 == m )
jp1 = 0;
var v0: Vertex3D = vertices[ j ];
var v1: Vertex3D = vertices[ jp1 ];
if ( usedInFaces[ v0 ] > 1 && usedInFaces[ v1 ] > 1 )
continue;
var c0: Vertex3D = cloned[ j ];
var c1: Vertex3D = cloned[ jp1 ];
geometry.faces.push( new Face3D( [ v0, c0, v1 ] ) );
geometry.faces.push( new Face3D( [ v1, c1, c0 ] ) );
}
}
}
private function cloneVertex( vertex: Vertex3D ): Vertex3D
{
var clone: Vertex3D = new Vertex3D( vertex.x, vertex.y, vertex.z );
clone.extra = vertex.extra;
return clone;
}
private function inArray( a: Array, v: Vertex3D ): Boolean
{
var n: int = a.length;
for ( var i: int = 0; i < n; i )
{
if ( ( a[ i ] as Array )[ int( 0 ) ] == v )
return true;
}
return false;
}
}
class NormalExtrude
{
public function NormalExtrude( geometry: GeometryObject3D, face: Face3D, distance: Number )
{
var v0: Vertex3D = face.vertices[ int( 0 ) ];
var v1: Vertex3D = face.vertices[ int( 1 ) ];
var v2: Vertex3D = face.vertices[ int( 2 ) ];
var c0: Vertex3D = cloneVertex( v0 );
var c1: Vertex3D = cloneVertex( v1 );
var c2: Vertex3D = cloneVertex( v2 );
geometry.vertices.push( c0, c1, c2 );
const normal: Number3D = calcNormal( face );
applyDistance( c0, normal, distance );
applyDistance( c1, normal, distance );
applyDistance( c2, normal, distance );
geometry.faces.push( new Face3D( [ c0, c1, c2 ] ) );
var cloned: Array = [ c0, c1, c2 ];
var jp1: int;
for ( var j: int = 0; j < 3; j )
{
jp1 = j 1;
if ( jp1 == 3 )
jp1 = 0;
v0 = face.vertices[ j ];
v1 = face.vertices[ jp1 ];
c0 = cloned[ j ];
c1 = cloned[ jp1 ];
geometry.faces.push( new Face3D( [ v0, c0, v1 ] ) );
geometry.faces.push( new Face3D( [ v1, c1, c0 ] ) );
}
}
private function applyDistance( vertex: Vertex3D, normal: Number3D, distance: Number ): void
{
vertex.x = normal.x * distance;
vertex.y = normal.y * distance;
vertex.z = normal.z * distance;
}
private function cloneVertex( vertex: Vertex3D ): Vertex3D
{
var clone: Vertex3D = new Vertex3D( vertex.x, vertex.y, vertex.z );
clone.extra = vertex.extra;
return clone;
}
private function calcNormal( face: Face3D ): Number3D
{
var normal: Number3D = new Number3D;
var v0: Vertex3D = face.vertices[ int( 0 ) ];
var v1: Vertex3D = face.vertices[ int( 1 ) ];
var v2: Vertex3D = face.vertices[ int( 2 ) ];
var t0: Vertex3D = new Vertex3D;
var t1: Vertex3D = new Vertex3D;
t0.x = v0.x - v1.x;
t0.y = v0.y - v1.y;
t0.z = v0.z - v1.z;
t1.x = v1.x - v2.x;
t1.y = v1.y - v2.y;
t1.z = v1.z - v2.z;
normal.x = t0.y * t1.z - t0.z * t1.y;
normal.y = t0.z * t1.x - t0.x * t1.z;
normal.z = t0.x * t1.y - t0.y * t1.x;
var length: Number = Math.sqrt( normal.x * normal.x normal.y * normal.y normal.z * normal.z );
if ( length == 0 )
length = 1;
normal.x /= length;
normal.y /= length;
normal.z /= length;
return normal;
}
}