Thread: [Plib-users] modifying materials of loaded models on the fly
Brought to you by:
sjbaker
From: Jakob G. <pi...@st...> - 2006-02-11 11:14:11
|
Hi. I'm trying to change the material properties of AC3D models after I load them. (think of a bottle model which is then used to render bottles with different surface properties). I can, sort of, achieve this following Steve Bakers earlier suggestion of locating the ssgSimpleState objects in the loaded model and then modifying them. However, it only works if I update and replace ALL of them. I was hoping I could just do myLeaf->setState(NULL) on all but the first one, and that the state set when starting the rendering would then "carry through" throughout the render of the whole object. Instead, this leaves the rest of the object uncoloured/white. There is one optimization that seems to work though - I can pick up the first ssgSimpleState, and then replace all the subsequent ssgstates with it. From this I at least get, that I only have to modify attributes of one ssgState. So my question: Am I just misunderstanding how SSG works - does each and every ssgLeaf need its own separate ssgState? I would have thought that 'last used state' would carry through for ssgLeafs with NULL ssgState? I include part of the code here, to illustrate what I'm doing. class MyTraverser : public TraverserBase { public: ssgState* firstState; private: int leafType; virtual bool visit(ssgEntity* pEnt) { if (!pEnt->isAKindOf(leafType)) { return true; // search on } ssgLeaf* pLeaf = static_cast<ssgLeaf*>(pEnt); ssgState* leafState = pLeaf->getState(); if (leafState != NULL) { if (firstState == NULL) { firstState = leafState; } else { //pLeaf->setState(NULL); //pLeaf->setState(new ssgSimpleState); pLeaf->setState(firstState); } /* ssgSimpleState* thestate = static_cast<ssgSimpleState*>(leafState); thestate->set(GL_COLOR_MATERIAL, false); thestate->setMaterial(GL_DIFFUSE, 0.99, 0.1, 0.1, 1.0); thestate->setMaterial(GL_AMBIENT, 0.6, 0.2, 0.4, 1.0); thestate->setMaterial(GL_SPECULAR,0.4, 0.6, 0.2, 1.0); */ } return true; } public: MyTraverser() { leafType = ssgTypeLeaf(); firstState = NULL; } }; This I then call like this: ... MyTraverser trav; trav.findLeafs(my_ssgScene); if (trav.firstState) { ssgSimpleState* thestate = static_cast<ssgSimpleState*>(trav.firstState); thestate->set(GL_COLOR_MATERIAL, false); // nothing worked without this... thestate->setMaterial(GL_DIFFUSE, 0.99, 0.1, 0.1, 1.0); thestate->setMaterial(GL_AMBIENT, 0.6, 0.2, 0.4, 1.0); thestate->setMaterial(GL_SPECULAR,0.4, 0.6, 0.2, 1.0); } ssgFlatten(themodel); ssgStripify(tra); I hope some more experienced users can clarify this. Cheers and thanks in advance, Jakob Gaardsted. |
From: Jakob G. <pi...@st...> - 2006-02-11 12:00:30
|
> So my question: Am I just misunderstanding how SSG works > - does each and every ssgLeaf need its own separate ssgState? > I would have thought that 'last used state' would carry through for > ssgLeafs with NULL ssgState? A clarification to this: I know that when/if I set the same ssgState pointer in all of the places, of course in a way I don't have "separate" states. But I was hoping SSG would avoid comparing the states and checking whether it should update the state or not (being NULL is a pretty solid indicator that you're not going to change any state...) Cheers, Jakob. |
From: Jakob G. <pi...@st...> - 2006-02-12 09:36:46
|
Hi. I have some pre-SSG/own code, I'm trying to migrate to SSG. However, my camera code screws up; it's as if the axes are switched, or worse. For example, my code has a direction/rotation matrix, that indicates the users' rotation around the y axis (it could be a rotation angle instead, but I'm exploiting that it's a matrix). However, when I multiply this matrix onto the ssg camera, it rotates around the _Z_ axis instead! Similar problems happen with other parts of the transform (which I've commented out to dissect the problem). I wonder if it's a left/righthand coordsys screwup, or maybe that I get the perspective configured wrongly... Here snippets from the code that I hope include enough info to illustrate what I'm doing: // this updates the direction rotate-matrix that at least has worked OK "until SSG": ... case GLUT_KEY_LEFT: direction.Rotate(-rotateStep, 0,1,0); break; case GLUT_KEY_RIGHT: direction.Rotate( rotateStep, 0,1,0); break; ... // this how I try to apply my camera for SSG: virtual void cameraForSSG(sgMat4& mat) { sgMakeIdentMat4(mat); sgPostMultMat4(mat, direction.a); ... (+ more similar code currently commented out to isolate the problem. } And finally, the render code context it's called from. Note that this first does non-SSG render, but that... shouldn't be a problem, as far as I understand? (the whole point of the exercise is to gradually move all the non-ssg code to ssg... So I like to let the non-ssg code do its thing until I know a given part works well with ssg). virtual void renderHandler() { // draw/callback function. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // reset modelview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); nav->renderSetCamera(); data.world.RenderMe(); // now render ssg glLoadIdentity(); // not really necessary, but not dangerous either? sgMat4 cameraMat; nav->cameraForSSG(cameraMat); ssgSetCamera(cameraMat); ssgCullAndDraw(my_ssgScene); // and here/now it's all wrong... glutSwapBuffers(); // necessary change for double buffer mode. } One of the things I wondered might be a problem, could be that maybe I don't succeed in configuring the non-ssg frustrum and the ssg frustrum the same way. The non-ssg frustrum I set with gluPerspective(). The ssg frustrum I set this way: class FrustumArgs { public: GLfloat top,bottom,left,right,znear,zfar; FrustumArgs() { top=bottom=left=right=znear=zfar= 0.0; } void calcFromPerspective( GLfloat vFovDeg, // 60.0f, // vertical fov GLfloat aspectRatio, GLfloat near_, //0.2, // 1.0, // near clipping plane GLfloat far_ //400.0 // far clipping plane ) { // JG: I call them 'z' because near/far seems to be C++ keywords... znear = near_; zfar = far_; GLfloat vFovRad = vFovDeg * SG_DEGREES_TO_RADIANS; //SG_PI/360.0; // from openGL faq: based on fact that // vFov*0.5 == atan( (top-bottom)*0.5 / near) top = tan(vFovRad*0.5)*znear; bottom = -top; left = bottom * aspectRatio; right = top * aspectRatio; } }; And then I use it like this: ... gluPerspective( 60.0f, // vertical fov fAspect, 0.2, // 1.0, // near clipping plane 400.0 // far clipping plane ); frustrumArgs.calcFromPerspective( 60.0f, // vertical fov fAspect, 0.2, // 1.0, // near clipping plane 400.0 // far clipping plane ); ssgSetFrustum( frustrumArgs.left, // JG: I now know that frustrumArgs.right, // left/r/b/t is the size of the 'rectangle' at distance znear! frustrumArgs.bottom, frustrumArgs.top, frustrumArgs.znear, frustrumArgs.zfar ); .... Actually, I don't think this part is the problem, because I think the ssg frustrum "wins" - the gluPerspective is only set once, so after a certain point only the ssg frustrum gets set, again and again (at least I assume); so the ssg frustrum is used for all (and the camera stuff still works OK for all the non-ssg stuff rendered at the same time). Cheers, and grateful for any help/suggestions/comments offered, Jakob Gaardsted. |
From: <coz...@gm...> - 2006-02-12 20:48:57
|
> > Hi. I have some pre-SSG/own code, I'm trying to migrate to SSG. > However, my camera code screws up; it's as if the axes are switched, or > worse. > > For example, my code has a direction/rotation matrix, that indicates > the users' rotation around the y axis (it could be a rotation angle > instead, > but I'm exploiting that it's a matrix). > > However, when I multiply this matrix onto the ssg camera, it rotates > around > the _Z_ axis instead! > Similar problems happen with other parts of the transform (which I've > commented out to dissect the problem). This is a quote from a page at Steve Baker's tuxkart site at http://tuxkart.sourceforge.net/trackdesign.html : "I come from a flight-simulation background where we use the convention tha= t Z-is-up - so all my software works like that. However, the PLIB loaders kno= w that some modellers use Y-is-up and do the axis swap as needed. Hence, in AC3D, Y-is-up - but in the game, your models will be converted to Z-is-up. If you find this confusing, forget I mentioned it - everything comes out OK automagically." So I would beleive the Z axis is the Y axis are swapped in plib, so just swapping these values when you load models and in your coordinate handling code would do the trick. -Coz |
From: Jakob G. <pi...@st...> - 2006-02-13 08:17:09
|
Thank you very very much! This was the only thing I hadn't considered... Considering the totally different directions I was looking for the = problem in, you've saved me very much frustration... ----- Original Message -----=20 From: Eduardo Alberto Hern=E1ndez Mu=F1oz=20 To: pli...@li...=20 Sent: Sunday, February 12, 2006 9:48 PM Subject: Re: [Plib-users] ssg camera woes / tranformation/coordsystem = confusion Hi. I have some pre-SSG/own code, I'm trying to migrate to SSG.=20 However, my camera code screws up; it's as if the axes are switched, = or worse. For example, my code has a direction/rotation matrix, that indicates the users' rotation around the y axis (it could be a rotation angle = instead,=20 but I'm exploiting that it's a matrix). However, when I multiply this matrix onto the ssg camera, it rotates = around the _Z_ axis instead! Similar problems happen with other parts of the transform (which = I've=20 commented out to dissect the problem). This is a quote from a page at Steve Baker's tuxkart site at = http://tuxkart.sourceforge.net/trackdesign.html : "I come from a flight-simulation background where we use the = convention that Z-is-up - so all my software works like that. However, = the PLIB loaders know that some modellers use Y-is-up and do the axis = swap as needed. Hence, in AC3D, Y-is-up - but in the game, your models = will be converted to Z-is-up. If you find this confusing, forget I = mentioned it - everything comes out OK automagically." So I would beleive the Z axis is the Y axis are swapped in plib, so = just swapping these values when you load models and in your coordinate = handling code would do the trick. -Coz -------------------------------------------------------------------------= ----- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.1.375 / Virus Database: 267.15.6/257 - Release Date: = 10/02/2006 |
From: Paolo L. <p.l...@ci...> - 2006-02-13 09:56:35
|
> -----Messaggio originale----- > Da: pli...@li... [mailto:pli...@li...]=20 > Per conto di Eduardo Alberto Hern=E1ndez Mu=F1oz > Inviato: domenica 12 febbraio 2006 21.49 > A: pli...@li... > Oggetto: Re: [Plib-users] ssg camera woes / tranformation/coordsystem confusion >=20 >=20 > > Hi. I have some pre-SSG/own code, I'm trying to migrate to SSG.=20 > > However, my camera code screws up; it's as if the axes are switched, = or > > worse. > >=20 > > For example, my code has a direction/rotation matrix, that indicates > > the users' rotation around the y axis (it could be a rotation angle instead,=20 > > but I'm exploiting that it's a matrix). > >=20 > > However, when I multiply this matrix onto the ssg camera, it rotates around > > the _Z_ axis instead! > > Similar problems happen with other parts of the transform (which = I've=20 > > commented out to dissect the problem). >=20 >=20 > This is a quote from a page at Steve Baker's tuxkart site at > http://tuxkart.sourceforge.net/trackdesign.html : >=20 > "I come from a flight-simulation background where we use the = convention that Z-is-up - so all my > software works like that. However, the PLIB loaders know that some modellers use Y-is-up and do > the axis swap as needed. Hence, in AC3D, Y-is-up - but in the game, = your models will be converted > to Z-is-up. If you find this confusing, forget I mentioned it - = everything comes out OK automagically." >=20 > So I would beleive the Z axis is the Y axis are swapped in plib, so = just swapping these values when you > load models and in your coordinate handling code would do the trick. >=20 > -Coz To be more precise, the matrix used for such SSG to OpenGL coordinate adaption can be found in ssg.cxx: sgMat4 _ssgOpenGLAxisSwapMatrix =3D { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } } ; This actually describes a 90=B0 rotation around the x-axis, in such a = way that SSG is "z+ is up, y+ points towards the observer", OpenGL is "y+ is up, = z+ points inside the screen" (I think it's the same handness). Greetings - Paolo Leoncini |