ASF / AMC import to skeleton.xml

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.

ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Thu Aug 12, 2010 2:42 pm

So, for my own purposes, I wanted to draw upon Carnegie Mellon's extensive motion capture database which is in ASF/AMC format for compatibility. I could find no extant utilities for importing these files, and I could only find one reference to importing them on the forums (and the fellow in question decided to instead switch to BVH). Right now, I have a Perl script to import an ASF and an AMC file and export a .skeleton.xml file. I'm looking at enhancing it to pull in additional animations and information off of the mocap pages like the names of the animations.

Would anybody be interested in this if I posted it?
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby sparkprime » Thu Aug 12, 2010 6:37 pm

What kind of data are we looking at here? Meshes would have to be made-to-fit for these animations, right?
User avatar
sparkprime
Ogre Magi
 
Posts: 1137
Kudos: 19
Joined: 07 May 2007
Location: Ossining, New York

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Thu Aug 12, 2010 7:06 pm

:) Yeah, that's the first problem. I'm fiddling with the Pinnochio implementation to be able to fit skeletons to meshes automatically, but of course, then one gets into retargetting issues. *shrug* It's a first step in the process, same as most import of motion capture data. Mainly, I wound up with the Perl script and wondered whether it was worth cleaning it up and posting it, or if either no one particularly cared to import AMC files and/or the problem's considered so trivial that people just code it on the fly.
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby sparkprime » Fri Aug 13, 2010 1:05 am

I would at least post it, if you clean it up and post it all the better. It's nice for someone to be able to find it if they're searching for something to do that even years after you've moved on.
User avatar
sparkprime
Ogre Magi
 
Posts: 1137
Kudos: 19
Joined: 07 May 2007
Location: Ossining, New York

Re: ASF / AMC import to skeleton.xml

Postby jacmoe » Fri Aug 13, 2010 7:14 am

That would be awesome! :)

People have been asking for this for some time.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
 
Posts: 20570
Kudos: 181
Joined: 22 Jan 2004
Location: Denmark

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Mon Aug 16, 2010 2:33 pm

It's cruder than I would like, and I've only tested it on CMU's input, but it seems to work so far:

Code: Select all
#!/usr/bin/perl -w
#
# Convert 'amc' and 'asf' to '.skeleton.xml' -- OGRE3D Skeleton format.
#

use XML::Writer;
use IO::File;
use Math::Quaternion;

my $frameInterval = 1.0/60.0;      # This constant measures the number of seconds between frames, here 60 frames per second

my $skel;
my $motion;

if (@ARGV == 2) {
   ($skel, $motion) = @ARGV;
} elsif (@ARGV == 1) {
   $skel = $ARGV[0];
   $motion = "";
} else {
   print "Please pass the name of an asf file and, optionally, the name of an amc file.\n";
   exit;
}

my $outfile = $skel;
$outfile =~ s/\.asf$/.skeleton.xml/;

if (!(-e $skel)) {
   print "Skeleton file '$skel' doesn't exist.\n";
   exit;
}

if ("" ne $motion && !(-e $motion)) {
   print "Motion file '$motion' doesn't exist.\n";
   exit;
}

my $output = new IO::File(">$outfile");

my $writer = new XML::Writer(OUTPUT => $output, DATA_MODE => 1, DATA_INDENT => 2);

$writer->startTag('skeleton');

open SKEL, "<", $skel;

my %dof; #degree-of-freedom count for each bone
my %direction; #direction vector for each bone
my %length; #length vector for each bone
my %children; #children array for each bone.

my @bones;   #An array of references to each bone's name in the original order

# We really should check the root object for its possible DOF.
# tx, ty, tz, rx, ry, rz, and l

my @dof;
my $line;

while (defined($line = <SKEL>) && !($line =~ /^:bonedata/)) {
   chomp($line);
   
   $line =~ s/\r$//;
   if ($line =~ s/^\s*order\s+//) {
      while ($line =~ s/^([rt][xyz]|l)\s*//i) {
         push @dof, uc($1);
      }
   }
   elsif ($line =~ s/^\s*axis\s+//) {
      # Do nothing. We have nothing to do with this information.
   }
   elsif ($line =~ s/^\s*position\s+//) {
      $position = $line;
   }
   elsif ($line =~ s/^\s*orientation\s+//) {
      $orientation = $line;
   }
   else {
      #ignore.
   }
}


$dof{"root"} = [@dof];
$children{"root"} = [];
push @bones, "root";
$direction{"root"} = "0 1 0";
$length{"root"} = "0";

if ($line !~ /^:bonedata/)
{
   while (defined($line = <SKEL>) && !($line =~ /^:bonedata/)) {
      #get to bone data.
   }
}

while (defined($line = <SKEL>) && ($line =~ /begin/)) {
   my $name = "";
   my @dof = ();
   my $axis = "";
   my $direction = "";
   my $length = "";
   while (defined($line = <SKEL>) && !($line =~ /end/)) {
      chomp($line);
      $line =~ s/\r$//;
      if ($line =~ /^\s*name\s+([^\s]+)/) {
         $name = $1;
      }
      elsif ($line =~ s/^\s*dof\s+//) {
         while ($line =~ s/^([r][xyz])\s*//) {
            push @dof, uc($1);
         }
      }
      elsif ($line =~ s/^\s*axis\s+//) {
         $axis = $line;
      }
      elsif ($line =~ s/^\s*direction\s+//) {
         $direction = $line;
      }
      elsif ($line =~ s/^\s*length\s+//) {
         $length = $line;
      }
      else {
         #ignore.
      }
   }
   $name ne "" || die "Bone with no name!";
   $direction ne "" || die "Bone with no direction!";
   $length ne "" || die "Bone with no length!";
   !(exists $dof{$name}) || die "Bone $name with duplicate name!";
   
   $children{$name} = [];
   $dof{$name} = [@dof];
   $direction{$name} = $direction;
   $length{$name} = $length;
   
   push @bones, $name;
}

if (!($line =~ /^:hierarchy/)) {
   while (defined($line = <SKEL>) && !($line =~ /^:hierarchy/)) {
      #get to hierarchy.
   }
}

while (defined($line = <SKEL>) && !($line =~ /^\s*begin/)) {
   #get to hierarchy begin.
}
while (defined($line = <SKEL>) && !($line =~ /^\s*end/)) {
   chomp($line);
   ($line =~ s/^\s*([^\s]+)//) || die "can't get first name in '$line'!";
   my $name = $1;
   (exists $children{$name}) || die "bone '$name' doesn't seem to exist!";
   while ($line =~ s/^\s*([^\s]+)//) {
      push @{$children{$name}}, $1;
   }
}

close SKEL;

$writer->startTag('bones');

my %boneFrames;

$count = 0;
foreach (@bones)
{
   $name = $_;
   $writer->startTag('bone', 'name' => $name, 'id' => "$count");
   
   @directions = split(/ /, $direction{$name});
   # We need to verify that there are 3 and then normalize the vector.
   scalar(@directions) == 3 || die "Not 3 values in $name direction";
   $directionlength = sqrt($directions[0] ** 2 + $directions[1] ** 2 + $directions[2] ** 2);
   if (abs($directionlength - 1) > 0.0001)
   {
      # Not a unit vector, so we normalize it.
      $directions[0] /= $directionlength;
      $directions[1] /= $directionlength;
      $directions[2] /= $directionlength;
   }
   
   $directions[0] *= $length{$name};
   $directions[1] *= $length{$name};
   $directions[2] *= $length{$name};
   
   $writer->emptyTag('position', 'x' => "$directions[0]"
                        , 'y' => "$directions[1]"
                        , 'z' => "$directions[2]");
                        
   # Check if valid DOF? Currently checked later in motion.
   
   # We're adding a boilerplate rotation since it requires one
   $writer->startTag('rotation', 'angle' => '0');
   $writer->emptyTag('axis', 'x' => '0', 'y' => '1', 'z' => '0');
   $writer->endTag('rotation');
   
   $writer->endTag('bone');
   $count++;
   
   my @frames;
   
   # Add an array for the frames of animation for this bone.
   $boneFrames{$name} = [@frames];
}

$writer->endTag('bones');

# Generate the hierarchy
$writer->startTag('bonehierarchy');

foreach(@bones)
{
   my $parent = $_;
   foreach(@{$children{$parent}})
   {
      $writer->emptyTag('boneparent', 'bone' => "$_",
         'parent' => "$parent");
   }
}

$writer->endTag('bonehierarchy');

$writer->startTag('animations');

if ("" ne $motion)
{
   open MOTION, "<", $motion;

   my @frames;   #Empty array to push the frames into.
   my $frame = 1;
   my $anglecorrection = 1;   # If radians, there's no correction.

   while (defined($line = <MOTION>) && !($line =~ /^$frame/)) {
      if ($line =~ /:DEG/)   # If the line :DEGREES or something similar shows up.
      {
         $pi = 3.14159;
         $anglecorrection =  1 * $pi / 180.0;
      }
      else
      {
         #Otherwise, we're just eating down to the frame
      }
   }
   while (1) {
      ++$frame;
      my %value_arrays;   # This array  holds the offsets of each of the frames.
      while (defined($line = <MOTION>) && !($line =~ /^$frame/)) {
         ($line =~ s/^([^\s]+)\s+//) || die "Expecting a bone name in '$line'.\n";
         my $name = $1;
         my @values = ();
         while ($line =~ s/^([^\s]+)\s+//) {
            push @values, ($1 + 0);
         }
         scalar(@values) == scalar @{$dof{$name}} || die "Frame " . ($frame - 1) . ": got the wrong number of values (" . scalar(@values) . ", expecting " . scalar @{$dof{$name}} . ") for $name.";
         
         push @{$boneFrames{$name}}, [$frame - 1, @values];
      }

      if (!(defined($line))) {
         last;
      }
   }

   close MOTION;

   $writer->startTag('animation', 'name' => 'anim1', 'length' => ($frame - 1) * $frameInterval);

   $writer->startTag('tracks');

   foreach (@bones)
   {
      my $name = $_;
      
      if (scalar (@{$boneFrames{$name}}) > 0)
      {
         $writer->startTag('track', 'bone' => $_);
         $writer->startTag('keyframes');
         
         foreach (@{$boneFrames{$name}})
         {
            my $frame = (shift @{$_}) - 1;
            $writer->startTag('keyframe', 'time' => $frame * $frameInterval);
            
            my @movementValues = @{$_};
            my $tempCounter = 0;
            
            my $tx = 0; my $ty = 0; my $tz = 0; my $rx = 0; my $ry = 0; my $rz = 0; my $l = 1;
            
            foreach(@{$dof{$name}})
            {         
               if(lc($_) eq "tx")
               {
                  $tx = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "ty")
               {
                  $ty = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "tz")
               {
                  $tz = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "rx")
               {
                  $rx = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "ry")
               {
                  $ry = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "rz")
               {
                  $rz = $movementValues[$tempCounter];
               }
               elsif(lc($_) eq "l")
               {
                  $l = $movementValues[$tempCounter];
               }
               else
               {
                  die "Unexpected DOF $_";
               }
               
               $tempCounter++;
            }
            
            if($tx != 0 or $ty != 0 or $tz != 0)
            {
               $writer->emptyTag('translate', 'x' => $tx, 'y' => $ty, 'z' => $tz);
            }
            
            if($rx != 0 or $ry != 0 or $rz != 0)
            {
               #Calculate the rotation angle.
               my $q = Math::Quaternion->from_euler($rx * $anglecorrection, $ry * $anglecorrection, $rz * $anglecorrection);
               
               $writer->startTag('rotate', 'angle' => $q->rotation_angle);
               my @v = $q->rotation_axis;
               
               $writer->emptyTag('axis', 'x' => $v[0], 'y' => $v[1], 'z' => $v[2]);
               $writer->endTag('rotate');
            }
            
            if($l != 1)
            {
               $writer->emptyTag('scale', 'factor' => $l);
            }
            $writer->endTag('keyframe');
         }
         $writer->endTag('keyframes');
         $writer->endTag('track');
      }
      
   }

   $writer->endTag('tracks');

   $writer->endTag('animation');
}

$writer->endTag('animations');

$writer->endTag('skeleton');

$writer->end();


There is one non-standard addition to the Math::Quaternion library. It lacked a function to create a quaternion from euler angles, so I added the following:
Code: Select all
sub from_euler {
   my $rx = $_[1];
   my $ry = $_[2];
   my $rz = $_[3];
   
   my $q0 = cos($rx / 2) * cos($ry / 2) * cos($rz / 2) + sin($rx / 2) * sin($ry / 2) * sin($rz / 2);
   my $q1 = sin($rx / 2) * cos($ry / 2) * cos($rz / 2) - cos($rx / 2) * sin($ry / 2) * sin($rz / 2);
   my $q2 = cos($rx / 2) * sin($ry / 2) * cos($rz / 2) + sin($rx / 2) * cos($ry / 2) * sin($rz / 2);
   my $q3 = cos($rx / 2) * cos($ry / 2) * sin($rz / 2) - sin($rx / 2) * sin($ry / 2) * cos($rz / 2);
   
   return Math::Quaternion->new($q0,$q1,$q2,$q3);
}
Last edited by FuzzyBoots on Thu Aug 19, 2010 2:18 am, edited 1 time in total.
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Mon Aug 16, 2010 2:35 pm

I'm having issues with the HTML processing (looks like it has to do with versions of Perl, which I am not free to change on this computer), so my next step will be to clean up the output by eliminating values which do not change from frame to frame. After that, I plan to try to find a way to detect anomolous input since the CMU dataset, at least, is known for the occasional frame where the values spike because it confused the markers.
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Tue Aug 17, 2010 6:31 am

*grumble* *grumble* *grumble* *grumble* And right now, the converter is choking on my output. Segmentation fault due to one of the imported bone pointers being NULL when exporting. I don't suppose someone could check this for me? A sample file without animations:

Code: Select all
<skeleton>

  <bones>

    <bone name="root" id="1">

      <position x="0" y="0" z="0" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lhipjoint" id="2">

      <position x="1.58895320509306" y="-1.83664936737439" z="0.717526745318765" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lfemur" id="3">

      <position x="2.50528204926557" y="-6.88321152190079" z="0" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="ltibia" id="4">

      <position x="2.63243820578737" y="-7.23257047807424" z="0" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lfoot" id="5">

      <position x="0.236910276096276" y="-0.650902556991898" z="1.72750248115058" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="ltoes" id="6">

      <position x="1.42137290088e-011" y="-3.90480693312e-011" z="0.925608" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rhipjoint" id="7">

      <position x="-1.51435423813563" y="-1.83664809465656" z="0.717526553818794" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rfemur" id="8">

      <position x="-2.54551384950135" y="-6.99374757552035" z="0" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rtibia" id="9">

      <position x="-2.66026494443553" y="-7.30902387705824" z="0" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rfoot" id="10">

      <position x="-0.229805115254575" y="-0.631383729311456" z="2.03958669917795" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rtoes" id="11">

      <position x="-1.643338882e-011" y="-4.517118344e-011" z="1.0706" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lowerback" id="12">

      <position x="-0.0265133514841054" y="1.86274648941361" z="-0.111518031144467" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="upperback" id="13">

      <position x="0.0101945571182134" y="1.86224356773346" z="0.0408749781716846" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="thorax" id="14">

      <position x="0.0217257767437695" y="1.86787590925687" z="0.0926804631123265" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lowerneck" id="15">

      <position x="-0.01926218556391" y="1.80512094393698" z="0.088668517340593" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="upperneck" id="16">

      <position x="0.0551565105621222" y="1.76450785142108" z="-0.384749499955467" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="head" id="17">

      <position x="0.0159181220178988" y="1.82587072232342" z="-0.140008602427061" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lclavicle" id="18">

      <position x="3.47116170282302" y="1.51376496379479" z="0.144910971779894" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lhumerus" id="19">

      <position x="4.78095" y="-2.14648877865e-010" z="1.52657167785e-026" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lradius" id="20">

      <position x="3.58615" y="-1.61006300705e-010" z="-1.3554714601e-026" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lwrist" id="21">

      <position x="1.79307" y="-8.0495753589e-011" z="2.296384749e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lhand" id="22">

      <position x="0.659812" y="-2.96279341232e-011" z="1.6900424568e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lfingers" id="23">

      <position x="0.531957" y="-2.38876354764e-011" z="2.7251093196e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="lthumb" id="24">

      <position x="0.54007896708213" y="-4.85013760357e-011" z="0.54007896708213" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rclavicle" id="25">

      <position x="-3.31724901441104" y="1.61216232503873" z="0.351559831344071" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rhumerus" id="26">

      <position x="-4.48913" y="-2.01548918523e-010" z="1.07265965698e-026" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rradius" id="27">

      <position x="-3.7051" y="-1.663404645e-010" z="1.6253088068e-026" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rwrist" id="28">

      <position x="-1.85255" y="-8.3180791785e-011" z="2.372560785e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rhand" id="29">

      <position x="-0.449136" y="-2.01595142736e-011" z="1.1504169504e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rfingers" id="30">

      <position x="-0.362105" y="-1.6263149444e-011" z="1.854991494e-027" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

    <bone name="rthumb" id="31">

      <position x="-0.36763330082026" y="-3.30066550973252e-011" z="0.36763330082026" />

      <rotation angle="0">

        <axis x="0" y="1" z="0" />

      </rotation>

    </bone>

  </bones>

  <bonehierarchy>

    <boneparent bone="lhipjoint" parent="root" />

    <boneparent bone="rhipjoint" parent="root" />

    <boneparent bone="lowerback" parent="root" />

    <boneparent bone="lfemur" parent="lhipjoint" />

    <boneparent bone="ltibia" parent="lfemur" />

    <boneparent bone="lfoot" parent="ltibia" />

    <boneparent bone="ltoes" parent="lfoot" />

    <boneparent bone="rfemur" parent="rhipjoint" />

    <boneparent bone="rtibia" parent="rfemur" />

    <boneparent bone="rfoot" parent="rtibia" />

    <boneparent bone="rtoes" parent="rfoot" />

    <boneparent bone="upperback" parent="lowerback" />

    <boneparent bone="thorax" parent="upperback" />

    <boneparent bone="lowerneck" parent="thorax" />

    <boneparent bone="lclavicle" parent="thorax" />

    <boneparent bone="rclavicle" parent="thorax" />

    <boneparent bone="upperneck" parent="lowerneck" />

    <boneparent bone="head" parent="upperneck" />

    <boneparent bone="lhumerus" parent="lclavicle" />

    <boneparent bone="lradius" parent="lhumerus" />

    <boneparent bone="lwrist" parent="lradius" />

    <boneparent bone="lhand" parent="lwrist" />

    <boneparent bone="lthumb" parent="lwrist" />

    <boneparent bone="lfingers" parent="lhand" />

    <boneparent bone="rhumerus" parent="rclavicle" />

    <boneparent bone="rradius" parent="rhumerus" />

    <boneparent bone="rwrist" parent="rradius" />

    <boneparent bone="rhand" parent="rwrist" />

    <boneparent bone="rthumb" parent="rwrist" />

    <boneparent bone="rfingers" parent="rhand" />

  </bonehierarchy>

  <animations>

   

  </animations>

</skeleton>
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Thu Aug 19, 2010 2:20 am

*facepalm* Alright, I'm not certain if this comes under bad implementation or me not understanding the spec. I was starting my IDs with 1. Apparently if you do that, you will never have "0" filled and therefore it fails immediately. Is the bones being in order from 0 to n-1 part of the specification or is it just so common of usage that no one thought to add a bounds check?
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby mr_mocap » Thu Aug 19, 2010 4:49 pm

FuzzyBoots wrote:*facepalm* Alright, I'm not certain if this comes under bad implementation or me not understanding the spec. I was starting my IDs with 1. Apparently if you do that, you will never have "0" filled and therefore it fails immediately. Is the bones being in order from 0 to n-1 part of the specification or is it just so common of usage that no one thought to add a bounds check?


Actually, according to specification, the "id" is optional. Internally, it will be automatically generated, but really it's only for keeping things unique, whether no duplicate body names exist or duplicate "id"'s exist.

It wouldn't surprise me that over the years, so many people started their "id"'s at zero that everyone now just writes code assuming that.
mr_mocap
Gnoblar
 
Posts: 6
Kudos: 0
Joined: 10 Apr 2007

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Fri Aug 20, 2010 10:12 am

mr_mocap wrote:Actually, according to specification, the "id" is optional. Internally, it will be automatically generated, but really it's only for keeping things unique, whether no duplicate body names exist or duplicate "id"'s exist.

It wouldn't surprise me that over the years, so many people started their "id"'s at zero that everyone now just writes code assuming that.

According to the DTD in Subversion, it's required:
Code: Select all
<!ATTLIST bone
   id      CDATA   #REQUIRED
   name   CDATA   #REQUIRED>

Still, the code should probably pull them in no matter what the IDs are and then just use those IDs for the Mesh attachment. ^_^ Yay! I have a project for a proposed code patch.
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010

Re: ASF / AMC import to skeleton.xml

Postby mr_mocap » Sat Aug 21, 2010 8:13 pm

FuzzyBoots wrote:
mr_mocap wrote:Actually, according to specification, the "id" is optional. Internally, it will be automatically generated, but really it's only for keeping things unique, whether no duplicate body names exist or duplicate "id"'s exist.

It wouldn't surprise me that over the years, so many people started their "id"'s at zero that everyone now just writes code assuming that.

According to the DTD in Subversion, it's required:
Code: Select all
<!ATTLIST bone
   id      CDATA   #REQUIRED
   name   CDATA   #REQUIRED>

Still, the code should probably pull them in no matter what the IDs are and then just use those IDs for the Mesh attachment. ^_^ Yay! I have a project for a proposed code patch.


And the ORIGINAL spec is here: http://www.mocap.co.nz/downloads/ASF_spec_v1.html

I also have a copy from the early 90's. Use the location above for future reference.... also for anyone else that needs to connect OGRE and ASF/AMC.

I suppose I should probably use my expertise to improve things, but I just have no extra time to spare.

Good Luck and keep us posted on your progress! :-)
mr_mocap
Gnoblar
 
Posts: 6
Kudos: 0
Joined: 10 Apr 2007

Re: ASF / AMC import to skeleton.xml

Postby mr_mocap » Sat Aug 21, 2010 8:14 pm

FuzzyBoots wrote:
mr_mocap wrote:Actually, according to specification, the "id" is optional. Internally, it will be automatically generated, but really it's only for keeping things unique, whether no duplicate body names exist or duplicate "id"'s exist.

It wouldn't surprise me that over the years, so many people started their "id"'s at zero that everyone now just writes code assuming that.

According to the DTD in Subversion, it's required:
Code: Select all
<!ATTLIST bone
   id      CDATA   #REQUIRED
   name   CDATA   #REQUIRED>

Still, the code should probably pull them in no matter what the IDs are and then just use those IDs for the Mesh attachment. ^_^ Yay! I have a project for a proposed code patch.


And the ORIGINAL spec is here: http://www.mocap.co.nz/downloads/ASF_spec_v1.html

I also have a copy from the early 90's. Use the location above for future reference.... also for anyone else that needs to connect OGRE and ASF/AMC.

I suppose I should probably use my expertise to improve things, but I just have no extra time to spare.

Good Luck and keep us posted on your progress! :-)
mr_mocap
Gnoblar
 
Posts: 6
Kudos: 0
Joined: 10 Apr 2007

Re: ASF / AMC import to skeleton.xml

Postby FuzzyBoots » Mon Aug 23, 2010 9:15 pm

Ah! I was speaking of the Ogre Skeleton.xml spec. ^_^ The ASF and AMC I can parse just fine. It's when I outputted the Skeleton.xml and tried to send it into the conversion tool that it failed.
FuzzyBoots
Gnoblar
 
Posts: 23
Kudos: 0
Joined: 12 Aug 2010


Return to Developer talk

Who is online

Users browsing this forum: No registered users and 3 guests