Egg question

In writting an egg exporter for blender, I ran into some whackyness with egg files. From what I understand.

For the joint structure I provided a matrix by which the weighted points are related. These are nested so the matrixes provided are offsets from the previous. The problem I’m running into is that, in the animation frames, it seems I have to respecify my position offsets to get it to work right, which doesn’t make sense to me.

wickwack.com/panda/simple.egg

is a very simple egg, 3 polys going up the global z axis. 3 bones the first being for the bottom 4 points the 2nd for the next 2 up and the 3rd for the remaning 2 verts at the top. The joints are nested and if you look in that file you’ll see the transforms offset relative to each other, but to get things to work I had to re issue the offsets in the animation.

I suppose I could just do it, but I’d like to understand why better.

I’m thinking that the offsets in the bones would be enough, and I wouldn’t need to re specific the offsets in the animation.

The transform that is specified in the animation completely replaces the transform that is specified for the corresponding joint in the joint structure. Thus, if you do not specify an offset in the animation, you are replacing the joint with a transform that has no offset.

That’s just the way the egg syntax was designed.

David

I seem to be running into issues when a bone is rotated from its parent. In the egg file referenced, it should look like a flat plane, there is only 1 frame of animation and it “attempts” to set the transform to the same transform as the joint specification, but things come out rotated.

Bone.One is the offending bone.

I’ll just post here vs putting on my site.


<CoordinateSystem> { Z-up }

<Material> Material { 
   <Scalar> diffr {0.616969525814}
   <Scalar> diffg {0.0}
   <Scalar> diffb {0.0}
   <Scalar> specr {1.0}
   <Scalar> specg {1.0}
   <Scalar> specb {1.0}
   <Scalar> shininess {0.5}
}
<Group> Plane {
  <Transform> {
    <RotX> { -90.000000 }
    <RotY> { 0.000000 }
    <RotZ> { -180.000000 }
    <Translate> { 0.000000 0.000000 0.000000 }
  }
  <Dart> {1}
  <VertexPool> PlaneMaterial {
    <Vertex> 0 { // Was mesh index 0
      -1.000000 -0.000000 -2.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 1 { // Was mesh index 3
      1.000000 0.000000 -2.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 2 { // Was mesh index 2
      1.000000 0.000000 -0.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 3 { // Was mesh index 1
      -1.000000 -0.000000 -0.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 4 { // Was mesh index 4
      -1.000000 -0.000000 -4.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 5 { // Was mesh index 5
      1.000000 -0.000000 -4.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 6 { // Was mesh index 7
      -1.000000 -0.000000 -6.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
    <Vertex> 7 { // Was mesh index 6
      1.000000 -0.000000 -6.000000
      <Normal> {
        0.000000 -1.000000 -0.000000
      }
      <UV> {
       0.000000 0.000000
      }
    }
  }
  <Polygon> {
    <Normal> {
      0.000000 -1.000000 0.000000 
    }
    <MRef> {
      Material
    }
    <VertexRef> {
      0 1 2 3
      <Ref> {
        PlaneMaterial
      }
    }
  }
  <Polygon> {
    <Normal> {
      0.000000 -1.000000 0.000000 
    }
    <MRef> {
      Material
    }
    <VertexRef> {
      1 0 4 5
      <Ref> {
        PlaneMaterial
      }
    }
  }
  <Polygon> {
    <Normal> {
      0.000000 -1.000000 0.000000 
    }
    <MRef> {
      Material
    }
    <VertexRef> {
      5 4 6 7
      <Ref> {
        PlaneMaterial
      }
    }
  }
  <Joint> root_Armature {
    <Transform> {
      <RotX> { 90.000000 }
      <RotY> { -180.000000 }
      <RotZ> { 0.000000 }
      <Translate> { 0.000000 0.000000 0.000000 }
    }
    <Joint> Bone {
      <Transform> {
        <RotX> { -90.000000 }
        <RotY> { 0.000000 }
        <RotZ> { 0.000000 }
        <Translate> { 0.000000 0.000000 0.000000 }
      }
      <VertexRef> {
         0  3  2  1 
        <Scalar> membership { 1.000000 }
        <Ref> { PlaneMaterial }
      }
      <Joint> Bone.One {
        <Transform> {
          <RotX> { 0.000004 }
          <RotY> { -24.999975 }
          <RotZ> { 24.999996 }
          <Translate> { 0.922618 2.093692 0.000000 }
        }
        <VertexRef> {
           4  5 
          <Scalar> membership { 1.000000 }
          <Ref> { PlaneMaterial }
        }
        <Joint> Bone.Two {
          <Transform> {
            <RotX> { -11.148418 }
            <RotY> { 22.521019 }
            <RotZ> { -27.226435 }
            <Translate> { -0.027675 2.117616 0.012905 }
          }
          <VertexRef> {
             7  6 
            <Scalar> membership { 1.000000 }
            <Ref> { PlaneMaterial }
          }
        }
      }
    }
  }
}
<Table> Plane_anims {
  <Bundle> Plane {
    <Table> "<skeleton>" {
      <Table> root_Armature {
        <Xfm$Anim> xform {
          <Scalar> contents { ijkphrxyz }
          <Scalar> order { sphrt }
          <Scalar> fps { 1 }
          <V> {
            1.000000 1.000000 1.000000 90.000000 0.000000 -180.000000 0.000000 0.000000 0.000000 
          }
        }
        <Table> Bone {
          <Xfm$Anim> xform {
            <Scalar> contents { ijkphrxyz }
            <Scalar> order { sphrt }
            <Scalar> fps { 1 }
            <V> {
              1.000000 1.000000 1.000000 -90.000000 0.000000 0.000000 0.000000 0.000000 0.000000 
            }
          }
          <Table> Bone.One {
            <Xfm$Anim> xform {
              <Scalar> contents { ijkphrxyz }
              <Scalar> order { sphrt }
              <Scalar> fps { 1 }
              <V> {
                1.000000 1.000000 1.000000 0.000004 24.999996 -24.999975 0.922618 2.093692 0.000000 
              }
            }
            <Table> Bone.Two {
              <Xfm$Anim> xform {
                <Scalar> contents { ijkphrxyz }
                <Scalar> order { sphrt }
                <Scalar> fps { 1 }
                <V> {
                  1.000000 1.000000 1.000000 -11.148418 -27.226435 22.521019 -0.027675 2.117616 0.012905 
                }
              }
            }
          }
        }
      }
    }
  }
}

There are two different problems working against you here.

First, since your egg file is Z-up, it means that “H” is defined as a rotation around the Z axis, and “R” is a rotation around the Y axis. Thus, you should define the initial transform Bone.One using:

        <Transform> {
          <RotX> { 0.000004 }
          <RotZ> { 24.999996 }
          <RotY> { -24.999975 }
          <Translate> { 0.922618 2.093692 0.000000 }
        }

to compose the rotations in the order p, h, r, to match your animation table.

Second, because you have chosen the order “sphrt”, you have triggered a special-case undocumented hack deep within the egg loader. Lucky you! :slight_smile:

We have this hack because, many years ago, in a precursor to Panda, the VR Studio used a different set of tools that read and wrote egg files–but we discovered later that these tools represented “R” in the reverse sense that they represented “H” and “P”. So we changed Panda to use a more consistent, intuitive direction for “R”, but then we still wanted to be able to load the legacy egg files that were written by these old tools. Since these old tools wrote animations out with the order “sphrt”, we made the egg loader automatically reverse “R” when it sees the order “sphrt”.

Long story short, to work around the hack, you should either use a different order, or reverse the sign of R (in the Table, but not in the Joint), like this:

          <Table> Bone.One {
            <Xfm$Anim> xform {
              <Scalar> contents { ijkphrxyz }
              <Scalar> order { sphrt }
              <Scalar> fps { 1 }
              <V> {
                1.000000 1.000000 1.000000 0.000004 24.999996 24.999975 0.922618 2.093692 0.000000
              }
            }

David

I had it rotated down. Fixing the quirky super deep hack worked. The reason I went with sphrt because of the spec doc, it has an example of:


  <Xfm$Anim> name {
      <Scalar> fps { 24 }
      <Scalar> order { sphrt }
      <Scalar> contents { ijkabcphrxyz }
      <V> { values }
  }

Just incase you want to change that.
I went with

order { sprht }

It seems to fix all the export issues I was having. Thanks

Ah, thank you. Yes, the original version of the specification doc was written back for the original egg loader. I’ve just fixed it to remove references to sphrt.

David

ah! that was another headhache! lost in the translation nightmare I have forgotten to point it out to Dave…good hint drWiggly