Anim8or Community

Please login or register.

Login with username, password and session length
Advanced search  

News:

Ian Ross has just released a book on Anim8or. It's perect for a beginner and a good reference for experienced users. It contains detailed chapters on every aspect, with many examples. Get your own copy here: "Anim8or Tutorial Book"

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - NickE

Pages: 1 [2] 3 4 ... 11
16
ASL Scripts / Re: SetFacePointIndex method
« on: December 31, 2015, 09:16:34 am »
The full code is below.  Unfortunately, I have opened and closed the mesh properly.

Code: [Select]
/* fix normals
   change all faces to the same orientation by starting with the first face.
   The direction of vertex winding is noted and compared to each edge adjacent face.
   If the direction of vertex winding is the same (should be opposite), fix it.
*/

/* section to initialize console output */
file $output;
string $fname;
$fname="$console";
$output.open($fname,"w");

object $curObject;
shape $shape, $shapes[0], $childShapes[1],$source;

int $havesource,$sourcenumpts,$sourcenumfaces,$sourcenumedges;

int $i,$j,$k,$m,$n;
int $tempedgeindex,$epi1,$epi2,$epi1_p,$epi2_p,$firstface;
int $tepi1,$tepi2,$tepi1_p,$tepi2_p;
int $f1,$f2;
int $cw1,$cw2;
int $flipped;
int $facestatus[0],$edgeface1[0],$edgeface2[0];
int $mainedge,$checkedge;
int $otherface;
int $ofptindex[0];

$curObject = project.curObject;
$curObject.GetShapes($childShapes);
$shapes.size = 0;
while ($childShapes.size > 0)
    $shapes.push($childShapes.pop());
   
while ($shapes.size > 0) {
    $shape = $shapes.pop();

    if ($shape.GetKind() == SHAPE_KIND_MESH && $havesource == 0)
    {
       $source=$shape;
       $sourcenumpts=$source.GetNumPoints();
       $sourcenumedges=$source.GetNumEdges();
       $sourcenumfaces=$source.GetNumFaces();
       $facestatus.size=$sourcenumfaces;
       $edgeface1.size=$sourcenumedges+1;
       $edgeface2.size=$sourcenumedges+1;
       $havesource=1;
    }
}

$shape.Open();
if ($havesource == 1) {
    /* build index of Edges to Faces to save cycles*/
    for $i = 1 to $sourcenumedges do
    {
        $firstface=0;
        for $j = 0 to $sourcenumfaces-1 do
        {
            for $k = 0 to $source.GetNumSides($j)-1 do
            {
                $tempedgeindex = $source.GetEdgeIndex($j,$k);
                if (abs($tempedgeindex) == $i) {
                    if ($firstface==0) {
                        $edgeface1[$i]=$j;
                    } else {
                        $edgeface2[$i]=$j;
                    }
                    $firstface=1;
                }
            }
        }
    }
   
    /* output list of the edges with the faces connected to it */
    for $i = 1 to $sourcenumedges do {
        $output.print("E:%d F1:%d F2:%d\n",$i,$edgeface1[$i],$edgeface2[$i]);
    }
   
   
    /* Cycle through faces edges to determine if adjacent faces have the same normals
       If the clockwise-counterclockwise order of face points is the same for adjacent faces,
       the normals are flipped
    */
   
    for $i = 0 to $sourcenumfaces-1 do {
        for $j = 0 to $source.GetNumSides($i)-1 do {
            $mainedge = $source.GetEdgeIndex($i,$j);                                /* current edge of current face */
            $epi1=$source.GetEdgeIndex0($mainedge);                                 /* end point of current edge */
            $epi2=$source.GetEdgeIndex1($mainedge);
            for $k = 0 to $source.GetNumSides($i)-1 do {
                if ($epi1==$source.GetFacePointIndex($i,$k)) $epi1_p=$k;            /* position in face vertex winding */
                if ($epi2==$source.GetFacePointIndex($i,$k)) $epi2_p=$k;
            }
            $output.print("F:%d E:%d ep1:(%d,%d) ",$i,$mainedge,$epi1_p,$epi2_p);
            if ($edgeface1[$mainedge] == $i) {                                     
                $otherface=$edgeface2[$mainedge];
            } else {
                $otherface=$edgeface1[$mainedge];
            }
            $ofptindex.size=$source.GetNumSides($otherface);                        /* retrieve other face with same edge */
            for $k = 0 to $source.GetNumSides($otherface)-1 do {
                $ofptindex[$k] = $source.GetFacePointIndex($otherface,$k);
                if ($epi1==$source.GetFacePointIndex($otherface,$k)) $tepi1_p=$k;   /* position in other face vertex winding */
                if ($epi2==$source.GetFacePointIndex($otherface,$k)) $tepi2_p=$k;
            }
            $output.print("F:%d E:%d ep1:(%d,%d) ",$otherface,$mainedge,$tepi1_p,$tepi2_p);
            if (abs($epi1_p - $epi2_p)==1) {                                        /* logic to determine direction of winding */
                if ($epi1_p > $epi2_p) {                                            /* can be simplified a bit :) */
                    $cw1=0;
                } else {
                    $cw1=1;
                }
            } else {
               if ($epi1_p > $epi2_p) {
                    $cw1=1;
               } else {
                    $cw1=0;
               }
            }

            if (abs($tepi1_p - $tepi2_p)==1) {
               if ($tepi1_p > $tepi2_p) {
                    $cw2=0;
               } else {
                    $cw2=1;
               }
            } else {
               if ($tepi1_p > $tepi2_p) {
                    $cw2=1;
               } else {
                    $cw2=0;
               }
            }
            $flipped=0;
            if ($cw1 == $cw2) $flipped=1;
            $output.print("->%d\n",$flipped);
            if ($cw1 == $cw2) {
                for $k = 0 to $source.GetNumSides($otherface)-1 do {
                    $source.SetFacePointIndex($otherface,$k,$ofptindex[$source.GetNumSides($otherface)-1-$k]);  /* reverse winding order of other face */
                    $output.print("Alter F:%d v:%d was:%d now:%d\n",$k,$otherface,$ofptindex[$k],$ofptindex[$source.GetNumSides($otherface)-1-$k]);
                }
            }
           
           
        }
    }
 }     

$shape.Close();
$output.close;

Thank you!

17
ASL Scripts / SetFacePointIndex method
« on: December 30, 2015, 06:56:01 pm »
I am trying to write an ASL script to essentially do what the Edit->Fix Normals command does.

I am using the technique of picking a face as the standard and testing whether the adjacent faces have the edges (or points) are wound in the same direction, then testing the adjacent to the adjacent, etc.  If I find a face that is wound in the same direction as the previous, I would like to reverse the winding.

I am trying to use the mesh.SetFacePointIndex method to do this:

Code: [Select]
for $k = 0 to $source.GetNumSides($otherface)-1 do {
   $source.SetFacePointIndex($otherface,$k,$ofptindex[$source.GetNumSides($otherface)-1-$k]);
}

where $ofptindex[] is the list of the index to the face points in the original order. 

I am working with a cube converted to a mesh as a test. E=EdgeIndex, F1:Face containing edge, F2:Other Face containing edge

Code: [Select]
E:1  F1:0 F2:5
E:2  F1:0 F2:3
E:3  F1:0 F2:4
E:4  F1:0 F2:2
E:5  F1:1 F2:2
E:6  F1:1 F2:4
E:7  F1:1 F2:3
E:8  F1:1 F2:5
E:9  F1:2 F2:4
E:10 F1:2 F2:5
E:11 F1:3 F2:5
E:12 F1:3 F2:4
So, if the original vtxIndex were [4,5,7,6], then the new would be [6,7,5,4].  Unfortunately, the above code results in three extra edges: 6-5, 5-5, and 4-4.

Code: [Select]
E:1  F1:0 F2:5
E:2  F1:0 F2:3
E:3  F1:0 F2:4
E:4  F1:0 F2:2
E:5  F1:1 F2:2
E:6  F1:1 F2:4
E:7  F1:1 F2:3
E:8  F1:1 F2:5
E:9  F1:2 F2:4
E:10 F1:2 F2:5
E:11 F1:3 F2:5
E:12 F1:3 F2:4
E:13 F1:0 F2:0 *
E:14 F1:0 F2:0 *
E:15 F1:0 F2:0 *

I am guessing that the extra edges are left over when the Face Point Index is re-assigned one vertex at a time.

Am I understanding the mesh.SetFacePointIndex method correctly?  What is the proper way to accomplish this?

Thank you!

18
ASL Scripts / Re: Boolean operation problem!
« on: December 11, 2015, 05:45:10 pm »
I have attached a different Boolean Operations script that might work in those tricky situations.  The instructions are a bit different, so be sure to read the header in the script file.


19
ASL Scripts / Re: BVH File Import into Anim8or
« on: July 03, 2015, 11:26:30 am »
SubDrag,

The file from the link is working fine for me.  I have attached the latest version of the program (executable and source) and the an8 file from the conversion.  The latest version is smarter about white space in the bvh file than the previous version.  I found that GoldenEye bvh files tend to use multiple spaces as a separator rather than the single space or tab.  In the previous version, multiple spaces as a separator would cause parsing errors.

The only parameter I changed in BVH2Animator is the scale factor to 0.15, so the figure (originally at 638) would not be so large (more like 100).

20
ASL Scripts / Re: BVH File Import into Anim8or
« on: June 15, 2015, 07:33:03 pm »
The missing pieces of required information is the reference frames for the rotations.  Does FBX use a right-handed or left-handed reference frame?  Are the skeletal orientation given in the global reference frame, object reference frame, or local reference frame?  Are the keyframe joint rotations given in the global reference frame, object reference frame, or local reference frame?

Since you already have the Anim8or skeleton constructed from the FBX file, you have some knowledge of the FBX reference frame.  Otherwise the skeleton would be distorted or rotated.   So, essentially what you need to do is transform the FBX Euler rotation angles from whatever reference frame they are in to the Anim8or local bone reference frame (the rotation of the bone relative to the parent).

The BVH2Anim8or source code routine "Calc_Figure_Orientation" calculates the each bone orientation relative to its parent bone.  The root bone (the ultimate parent) is located in the Anim8or global reference frame Left-Handed (0,1,0).  The routine "Calc_NetOrient" calculates the each bone orientation relative to the Anim8or global reference frame.  The routine "Calc_Sequence_Motion" transforms the BVH keyframe joint rotations to the Anim8or local bone reference frame.

I know this is very confusing and extremely frustrating.  While writing the BVH2Anim8or and SMD2Anim8or converters, I kept having to remind myself "What frame I am in?  What frame do the actions take place?  What frame does Anim8or need?"

21
ASL Scripts / Re: BVH File Import into Anim8or
« on: June 14, 2015, 07:45:39 pm »
All the math you need is in the BVH2Anim8or code.  I have also attached a SMD2Anim8or source.  It does something very similar. 

Anim8or does not use a 3 axis-angle format.  Anim8or uses quaternions to encode the orientation of the bone relative to its parent.

Do you have a link to the FBX format specification where it describes the reference frame for the bone orientations?

Please read the thread http://www.anim8or.com/smf/index.php/topic,5005.msg37381.html#msg37381 for some discussion of the math required.

22
ASL Scripts / Re: BVH File Import into Anim8or
« on: June 14, 2015, 05:04:46 pm »
SubDrag,
Can you please be more specific about what you are trying to do?  Euler angles relative to what?  Is there a source format you are using?

23
ASL Scripts / Re: BVH File Import into Anim8or
« on: June 13, 2015, 08:37:16 am »
The source code is for Visual Studio 2013 (available free).

Enjoy!

24
ASL Scripts / Re: Mesh to Mesh Morphing Hack
« on: May 30, 2015, 11:51:28 am »
I am sorry I did not explain the process very clearly.  I will post a step-by-step tutorial soon.

Until then, attached is the an8 file used to do the video.

25
Finished Works and Works in Progress / Re: Fun with Morphing
« on: May 30, 2015, 10:31:00 am »
I put an explanation with the scripts used for this video here: http://www.anim8or.com/smf/index.php/topic,5166.0.html

26
ASL Scripts / Mesh to Mesh Morphing Hack
« on: May 30, 2015, 10:29:50 am »
Mesh to Mesh Morphing Hack:

The idea behind this technique for mesh to mesh morphing is to have an intermediate shape "between" the starting and ending mesh rather than flowing smoothly from the starting to the ending mesh.  Direct morphing is prohibitive in Anim8or because it would require that one "map" specific areas of one mesh to the other mesh ahead of time.  Theoretically, the mapping could be done with textures, but it would be very slow and laborious.

When I first started playing with this technique, I wrote a script that would convert any mesh into a simple shape like a sphere, cylinder, cube, or any other easily definable shape.  Taking a mesh in Object Mode, creating a new "Morph Target" (Build->Morph Target->New...), then running the script, the points of the mesh are transformed to the desired shape.  In Scene Mode, you can watch the original mesh change into the simple shape and back by adjusting the scene morph target keys.

The next logical extension to this is to take two different meshes and convert each of them to the same sized intermediate shape.  In Scene Mode, you make the first mesh visible and unmorphed, the second mesh invisible and fully morphed, perfectly superimposed.  When the first mesh is fully morphed, make it invisible, make the second mesh visible and proceed to unmorph it back to its original shape.  You get the illusion that the first mesh flowed to the intermediate shape and then flowed into the second mesh.  This looks pretty cool and has many possibilities on its own.

The next logical extension is to try to get the illusion of flowing somewhat more smoothly from the starting mesh to the ending mesh by using scripting that allows the starting mesh to be transformed so that it "shrink wraps" the ending mesh.  Then, the ending mesh is transformed so that it "shrink wraps" the morph of the starting mesh.  After that, the same visibility tricks in Scene Mode are used.  That is how the video in http://www.anim8or.com/smf/index.php/topic,5165.msg38573.html is done.

A further note on "shrink wrapping" one mesh around another:  I convert the mesh that will be the "wrapper" to a sphere (To_Sphere.txt)that is larger than the target before applying the "shrink wrapping" script (ShrinkWrap_Target.txt).


27
Finished Works and Works in Progress / Fun with Morphing
« on: May 27, 2015, 08:02:13 pm »
I wrote a script to help morphing from one mesh to another.  It is kind of a hack where one superimposes the ending mesh on the starting mesh and runs the script while in the morph, then does the opposite (the starting on the ending) then uses scene mode visibility tricks.

28
ASL Scripts / ASL Command render() always crashes Anim8or
« on: February 02, 2015, 10:06:17 am »
Has anyone ever successfully used the render() command in an ASL script?  I have tried to use it off an on since V0.95, but it always crashes Anim8or.

I like to write scripts to do physics simulations, but these type of scripts only work object mode. (See topic http://www.anim8or.com/smf/index.php/topic,2358.msg25814.html#msg25814 for tricks required to render.)  It would be nice to be able to render the results of the simulations more easily.  Rendering from object mode is not ideal, but perhaps workable.

Another possibility is an Object Mode ASL command to switch to Scene Mode and render and save a particular frame before continuing:  RenderSceneFrame(int Frame,string Filename)

Any thoughts?

29
General Anim8or Forum / Re: SMD skeleton to an8 skeleton
« on: December 29, 2014, 04:54:07 pm »
Smirkguy,

The attached zip file contains the SMD2Anim8or conversion executable.  It works with all three of the SMD files you gave links to.

NickE

30
General Anim8or Forum / Re: SMD skeleton to an8 skeleton
« on: December 28, 2014, 08:38:03 pm »
Smirkyguy,
I do not have any other SMD example files to work from except the ones from Deepthough.  If you would post some files, I can try to alter the program to work with them.  The source code has been posted earlier, if you'd like to do it yourself.

NickE

Pages: 1 [2] 3 4 ... 11