<div dir="ltr"><div class="gmail_default" style="font-family:tahoma,sans-serif">Hi Hannes,</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">for the camera setup you're after I recommend using a SlaveUpdateCallback, which will be called once per frame for each slave camera, allowing you to manipulate the camera position/orientation at will. </div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">Here's a code snippet:</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default"><div class="gmail_default"><font face="monospace, monospace">// implement a slave callback to place the camera as you want</font></div><div class="gmail_default"><font face="monospace, monospace">class MySlaveCallback : public osg::View::Slave::UpdateSlaveCallback</font></div><div class="gmail_default"><font face="monospace, monospace">{</font></div><div class="gmail_default"><font face="monospace, monospace">   // implement update method</font></div><div class="gmail_default"><font face="monospace, monospace">   virtual void updateSlave(osg::View& view, osg::View::Slave& slave){ ... }</font></div><div class="gmail_default"><font face="monospace, monospace">}</font></div><div class="gmail_default"><font face="monospace, monospace"><br></font></div><div class="gmail_default"><font face="monospace, monospace">// add the camera as slave</font></div><div class="gmail_default"><font face="monospace, monospace">slaveCam->setGraphicsContext(gc);</font></div><div class="gmail_default"><font face="monospace, monospace">viewer.addSlave(slaveCam, true);</font></div><div class="gmail_default"><font face="monospace, monospace"><br></font></div><div class="gmail_default"><font face="monospace, monospace">// install your callback</font></div><div class="gmail_default"><font face="monospace, monospace">osg::View::Slave* slave = viewer.findSlaveForCamera(slaveCam);</font></div><div class="gmail_default"><font face="monospace, monospace">slave->_updateSlaveCallback = pMirrorCallback;</font></div><div class="gmail_default"><font face="tahoma, sans-serif"><br></font></div><div class="gmail_default"><font face="tahoma, sans-serif">Ricky</font></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 11, 2017 at 2:11 PM, Hannes Naude <span dir="ltr"><<a href="mailto:naude.jj@gmail.com" target="_blank">naude.jj@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I think I solved my own problem. I was planning to use <div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>viewer.addSlave(cam,...) </div></blockquote><div><br></div><div>and then use </div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>cam->setReferenceFrame(osg::<wbr>Transform::ABSOLUTE_RF) </div></blockquote><div><br></div><div>to decouple the slave camera from the master. (If this is not the best approach, I would still like to hear, but it seems pretty clean)</div><div><br></div><div>It turned out that I did not even need the second call. I think this is because I have an update callback attached to each of the slave cameras that explicitly sets the view matrix to match the world-to-local matrix of some node in the scenegraph and thereby overrides the slaving. </div><div><br></div><div>By the way, this is something else that has bothered me. The requirement for a camera to track a node in the scenegraph seems like it should be extremely common. But in order to implement this I had to write my own little NodeTracker Callback as follows: </div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>class NodeTracker : public NodeCallback</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>{</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>public:</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>   NodePath _nodepath;</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><br></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>   NodeTracker(Node* node):_nodepath(node-><wbr>getParentalNodePaths()[0]){}</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><br></div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>   virtual void operator()(Node* node, NodeVisitor* nv)</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>   {</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>  ref_ptr<Camera> cam=node->asCamera();</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">     </span>  if(cam)</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">    </span>  {</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">          </span>  Matrix mat2=cam->getViewMatrix();</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">               </span>  Matrix mat=computeWorldToLocal(_<wbr>nodepath);</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">              </span> cam->setViewMatrix(mat);</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>  }</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span class="m_732076141154945438gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>  traverse(node, nv);</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>   }</div></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>};</div></div><div><br></div></blockquote></blockquote><div>It feels like this is such a common requirement that something like it should be built into OSG. I had a look at the tutorial on the subject :</div><div><br></div><div><a href="http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/CameraControlNodeFollowing" target="_blank">http://trac.openscenegraph.<wbr>org/projects/osg//wiki/<wbr>Support/Tutorials/<wbr>CameraControlNodeFollowing</a><br></div><div><br></div><div>but it recommends a solution that seems even more generally useful and is quite verbose, yet is not included in osg. What am I missing here?</div><div><br></div><div>Regards</div><span class="HOEnZb"><font color="#888888"><div>Hannes Naude</div></font></span><div><div class="h5"><div><div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 11, 2017 at 1:08 PM, Hannes Naude <span dir="ltr"><<a href="mailto:naude.jj@gmail.com" target="_blank">naude.jj@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi all<div><br></div><div>I am trying to render a single scene from multiple viewpoints. I initially implemented this with a compositeviewer as per the osgthirdpersonview example. This worked fine except that my update callbacks appeared to be getting called more than once per render cycle. I assumed that the update traversal was being done for each view separately and therefore nodes that are present in multiple views will have their update callbacks called multiple times. So, at this point I tried to do the same thing but with a single View, somewhat similar to the osgCamera example. But, I do not want to add my cameras with viewer.addSlave as I want them to move independently of one another. So I tried adding them into the scene graph and giving each their own GraphicsContext, but even though the windows corresponding to these GraphicsContexts get created, it appears as if all rendering is done in a single window with multiple viewpoints being rendered over one another.</div><div><br></div><div>Obviously there are many ways to skin this cat, but I would appreciate some guidance on the recommended approach. To recap my requirements are :</div><div> - Multiple cameras viewing the same scene.</div><div> - Camera positions and orientations must be independently controlled.</div><div> - Node update callbacks should be called only once per Node per render cycle.</div><div><br></div><div>Any help will be appreciated</div><div><br></div><div>Regards</div><span class="m_732076141154945438gmail-HOEnZb"><font color="#888888"><div>Hannes Naude</div></font></span></div>
</blockquote></div><br></div></div></div></div></div>
<br>______________________________<wbr>_________________<br>
osg-users mailing list<br>
<a href="mailto:osg-users@lists.openscenegraph.org">osg-users@lists.<wbr>openscenegraph.org</a><br>
<a href="http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org" rel="noreferrer" target="_blank">http://lists.openscenegraph.<wbr>org/listinfo.cgi/osg-users-<wbr>openscenegraph.org</a><br>
<br></blockquote></div><br></div>