Matrix Extrude

Matrix Extrude

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.

Related Posts

4 Responses to “Matrix Extrude”


  1. 1 andrew

    Very nice! any chance to see the source code of it?
    thank u
    A.

  2. 2 joa

    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.

  3. 3 andrew

    ok :) do u have any link about that code needed to extrude a face?
    thank u!

  4. 4 joa

    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;
    }
    }

Leave a Reply






Close
E-mail It