Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Viewpoints with different Transforms?

2011-11-23
2013-06-12
  • James Sweet
    James Sweet
    2011-11-23

    I'm getting bizarre behavior when I try to initiate a smooth jump between two Viewpoints which are under a different set of Transform tags.  It sort of looks like it is immediately switching (no transition animation) to where the current Viewpoint would be if it were under the target Viewpoint's Transform, and then it does the transition animation… but it might be more than that.  Weird things happening.

    Making matters worse, I'm trying to change the relevant Transforms with an OrientationInterpolator, and that seems to get things really confused.

    Is this just not supported?  Or am I probably still doing something wrong?  It would be really cool to be able to do this, since I need to be able to automatically zoom in on particular features of a scene, but I also need to be able to animate those same features and have it still zoom in on the right place even after the feature has changed position.  It seems like I should be able to do this in X3D, but I'm wondering if X3DOM just doesn't support it.  (The convention seems to be to have all of your viewpoints not transformed, even though the X3D book I have says you can do it)

     
  • Dave A
    Dave A
    2011-11-23

    Are you getting world coords first? I've not tried in x3dom, but in x3d, if you have viewpoints under different transforms, their individual positions are relative to their containing transforms (all the way up to the root), so unless the platform supports doing this for you (as Contact does with an API) you would need to get world coords for both before lerping.

     
  • Yvonne Jung
    Yvonne Jung
    2011-11-27

    Do you have a little example that shows your problem. Unfortunately, it's not clear to me what exactly your are doing.

     
  • James Sweet
    James Sweet
    2011-11-28

    Sure, here's an example, and it doesn't even rely on the transform being changed by later animation.  First consider this example, which works, and should allow you to zoom in alternately on the red sphere or blue sphere:

    <!DOCTYPE html >
    <html>
      <head>
        <link rel="stylesheet" type="text/css" href="http://x3dom.org/x3dom/example/x3dom.css" />
        <script type="text/javascript" src="http://x3dom.org/x3dom/example/x3dom.js"></script>
      </head>  
      <body>
        <x3d xmlns="http://www.x3dom.org/x3dom" showStat="false" showLog="false" x="0px" y="0px" width="400px" height="400px" altImg="helloX3D-alt.png">
          <scene>
            <viewpoint id='redView' position='0 0 8' ></viewpoint>
            [b]<Viewpoint id='blueView' position='0 3 8' ></viewpoint>[/b]
            <shape>
              <appearance>
                <material diffuseColor='1 0 0' ></material>
              </appearance>
              <Sphere></Sphere>
            </shape>
        <Transform id='blueTransform' translation='0 3 0'>
              <shape>
                <appearance>
                  <material diffuseColor='0 0 1' ></material>
                </appearance>
                <Sphere></Sphere>
              </shape>
        </Transform>
          </scene>
        </x3d>    
        <input type="button" value="Red sphere" onclick="document.getElementById('redView').setAttribute('set_bind','true');"/>
        <input type="button" value="Blue sphere" onclick="document.getElementById('blueView').setAttribute('set_bind','true');"/>
      </body>
    </html>
    

    Now consider this example, where the only thing I have changed is that I have moved the Viewpoint "blueView" inside the Transform tag, and zeroed out the Y coordinate.  In other words, rather than making two Viewpoints up front that both magically know where the red sphere and blue sphere are going to be, I have two Viewpoints that just specify the distance from the object and I put them inside the appropriate transform:

    <!DOCTYPE html >
    <html>
      <head>
        <link rel="stylesheet" type="text/css" href="http://x3dom.org/x3dom/example/x3dom.css" />
        <script type="text/javascript" src="http://x3dom.org/x3dom/example/x3dom.js"></script>
      </head>  
      <body>
        <x3d xmlns="http://www.x3dom.org/x3dom" showStat="false" showLog="false" x="0px" y="0px" width="400px" height="400px" altImg="helloX3D-alt.png">
          <scene>
            <viewpoint id='redView' position='0 0 8' ></viewpoint>
            <shape>
              <appearance>
                <material diffuseColor='1 0 0' ></material>
              </appearance>
              <Sphere></Sphere>
            </shape>
        <Transform id='blueTransform' translation='0 3 0'>
              [b]<Viewpoint id='blueView' position='0 0 8' ></viewpoint>[/b]
              <shape>
                <appearance>
                  <material diffuseColor='0 0 1' ></material>
                </appearance>
                <Sphere></Sphere>
              </shape>
        </Transform>
          </scene>
        </x3d>    
        <input type="button" value="Red sphere" onclick="document.getElementById('redView').setAttribute('set_bind','true');"/>
        <input type="button" value="Blue sphere" onclick="document.getElementById('blueView').setAttribute('set_bind','true');"/>
      </body>
    </html>
    

    I get bizarre behavior in the second example for the blue sphere.  It jumps around and doesn't want to zoom in on the right place.  I have the same problem in both Chrome and Firefox, so I think it's X3DOM.

     
  • James Sweet
    James Sweet
    2011-12-06

    Ping!  Any thoughts?  Is this even supposed to work?  It's kind of causing me an issue, because otherwise I will need to do some serious math to figure out where the Viewpoints are supposed to go.  This toy example was intentionally easy, but in my real example, there are a number of arbitrarily nested rotations, and I just want to have a Viewpoint that basically says: "Zoom in on this IndexedFaceSet (wherever it happens to be right now) from a distance of D".  I can't just rely on the authoring tool to do it for me, because there is no authoring tool; this is dynamically-generated X3D to provide a visualization of a custom item that the user is dynamically creating.

     
  • jlummer
    jlummer
    2011-12-07

    Hi,

    what happens is the following: Maybe you have noticed already that when clicking "Blue sphere" the viewpoint in the second example does not jump on an arbitrary position. Every time you switch to blueView after redView the position goes to n*3 on the y-axis (n is the number of switches, 3 is the y-value of the 'translation' attribute in the <Transform> under which the <Viewpoint id='blueView'> is situated).
    So why is that? Roughly speaking X3DOM takes the viewMatrix of the former position of 'blueView' and adds the Transform value to it. So when the camera has been on y-value 6 the last time it jumps to 9 the next time.

    In the x3dom.js the function responsible for this behaviour is that one:

    x3dom.Viewarea.prototype.getViewpointMatrix = function() {
        var viewpoint = this._scene.getViewpoint();
        var mat_viewpoint = viewpoint.getCurrentTransform();
        return mat_viewpoint.mult(viewpoint.getViewMatrix());
    };
    

    viewpoint.getViewMatrix() gets the this._viewMatrix which is for the example above:

    _00: 1
    _01: 0
    _02: 0
    _03: 0
    _10: 0
    _11: 1
    _12: 0
    _13: -12
    _20: 0
    _21: 0
    _22: 1
    _23: -8
    _30: 0
    _31: 0
    _32: 0
    _33: 1

    To the -12 is then added a 3 of the <Transform> which gives a -9. As the _viewMatrix describes the world coordinate system in the camera coordinate system the blue sphere is now -9 away from the camera. That's why you can't see it anymore.

    To cut a long story short you probably can't solve your problem this way. You have to put your <Viewpoint>s above your geometry and find out the position of the objects by multiplying all parent <Transform>s of a single object writing that value into the 'translation' attribute of the <Viewpoint>.
    But fortunately X3DOM does that already for you ( x3dom.js):

    Context.prototype.renderScene = function(viewarea){
    ...
    var trafo = scene.drawableObjects[i][0];
    ...
    }
    

    Hope that helps!

    Regards.

     
  • jlummer
    jlummer
    2011-12-07

    Hi,

    to avoid confusing you: There was a copy and paste problem, the last code snippet should be

    var trafo = scene.drawableObjects[i][0];
    

    Regards.

     
  • jlummer
    jlummer
    2011-12-07

    OK, same problem again, it's because of the 'i'. Now another try:

    var trafo = scene.drawableObjects_;_

     
  • jlummer
    jlummer
    2011-12-07

    Obviously not my day:

    var trafo = scene.drawableObjects    i     (in brackets) ;

    Hopefully now :)!!!

     
  • James Sweet
    James Sweet
    2011-12-07

    Not following you 100%, but I get the gist:  Viewpoints inside Transforms are not properly supported in X3DOM, _but I should be able to use X3DOM to ask for the current transformation matrix of the object in question, and then set my viewpoint that way - which is much simpler than what I thought I would have to do, which is to have my code keep track of all of that math.

    It's not clear to me exactly how to do that, but just knowing that I can, I probably ought to be able to figure it out.  Thanks!_