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 ... 12
16
Anim8or v0.98 Discussion Forum / Re: Bug/Issue: Normals (ASL)
« on: March 08, 2016, 08:08:06 pm »
Raxx,

When I calculate the face normals from the average of the face vertex normals (calculated from the edge vectors from each point of the face), I do get different values than your script returns.  The edge vector calculated values return symmetrical normals for mirrored faces on your attached mesh.  I modified your script to add the manually calculated normals to the output.  You can see the variation in the individual vertex based face normals.  It seems the algorithm that Anim8or is using is significantly different or is suffering from a precision problem.

Code: [Select]
file $c;
shape $s, $childShapes[0];
int $i, $j, $k;
int $numSides;
point3 $faceNormal;

//added
int $l,$back,$fwd;
point3 $facePoint[0];
point3 $facePointNormal[0];
point3 $fPNavg;
 
$c.open("$console", "w");
 
project.curObject.GetShapes($childShapes);
 
for $i = 0 to $childShapes.size - 1 do
{
if($childShapes[$i].GetKind() == SHAPE_KIND_MESH)
{
$s = $childShapes[$i];
 
for $j = 0 to $s.GetNumFaces() - 1 do
{
if ($s.GetFaceSelected($j) == 1)
{
//$faceNormal = $s.GetNormal($s.GetFaceNormalIndex($j, 0));
$faceNormal=(0.0,0.0,0.0);
$fPNavg=(0.0,0.0,0.0);
$numSides = $s.GetNumSides($j);
        $facePoint.size = $numSides;
        $facePointNormal.size = $numSides;
for $k = 0 to $numSides - 1 do
{
$faceNormal = $faceNormal + $s.GetNormal($s.GetFaceNormalIndex($j, $k));
$facePoint[$k]=$s.GetPoint($s.GetFacePointIndex($j,$k));
$facePointNormal[$k]=(0.0,0.0,0.0);
}
 
$faceNormal = normalize(($faceNormal.x/(1.0 * $numSides), $faceNormal.y/(1.0 * $numSides), $faceNormal.z/(1.0 * $numSides)));

for $k = 0 to $numSides-1 do
{
          $back = $k - 1;
          if ($back < 0) $back = $numSides - 1;
          $fwd = $k + 1;
          if ($fwd > ($numSides - 1)) $fwd = 0;
          $facePointNormal[$k] = normalize(cross(($facePoint[$back]-$facePoint[$k]),($facePoint[$fwd]-$facePoint[$k])));
          $c.print("Calc FP %d Normal (%.3f,%.3f,%.3f)\n",$k,$facePointNormal[$k]);
          $fPNavg = $fPNavg + $facePointNormal[$k];
        }
        $fPNavg = normalize(($fPNavg.x / (1.0 * $numSides),$fPNavg.y / (1.0 * $numSides),$fPNavg.z / (1.0 * $numSides)));
$c.print("Face %d Anim8or normals (%.3f, %.3f, %.3f) Calc (%.3f, %.3f, %.3f)\n", $j, $faceNormal, $fPNavg);
}
}
}
}
 
$c.close();
 

NickE

17
ASL Scripts / Re: BVH File Import into Anim8or
« on: January 24, 2016, 11:51:51 am »
RemiD,
Like Claude posted, if you post the BHV file and parameters, I will take a look.  Often, these issue happen because so many different BVH generators write slightly differing formats that the parser does not anticipate or the file is simply malformed.

NickE

18
ASL Scripts / Re: SetFacePointIndex method
« on: January 07, 2016, 12:39:01 pm »
Kreator,

I am not sure which script your are referring to as "parametric SourceMesh2Target".

If you are referring to the parametric script in http://www.anim8or.com/smf/index.php/topic,906.msg6613.html#msg6613 called "mesh2mesh_1.a8s", I tested it in Build 1205 and it worked fine for me.  You kind of have to click the script button, then sort of click-drag a bit in some open area and the parametric copies appear.

What behavior are you seeing?

Thank you,
NickE

19
ASL Scripts / Re: SetFacePointIndex method
« on: January 06, 2016, 01:52:07 pm »
Kreator,

When I ran through the tank tread tutorial (including downloading the scripts posted there) on Build 1205, it worked properly.

Also the mesh_2_path_2 worked properly without hanging when I tried it.

Could it be something unique to your setup?  I am happy to help in any way.

20
ASL Scripts / Re: SetFacePointIndex method
« on: January 05, 2016, 08:38:32 am »
Claude,
Luckily, "new" edges are always added to the end of the list, so as a workaround, I can just delete them without it causing problems with rearranging the index.

Kreator,
I had no idea that these scripts had stopped working.  I haven't used them in quite some time.  I will investigate further.

Steve,
Thank you!

21
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!

22
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!

23
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.


24
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).

25
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?"

26
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.

27
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?

28
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!

29
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.

30
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

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