• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

AbhijitNandy

Members
  • Content count

    13
  • Joined

  • Last visited

Community Reputation

108 Neutral

About AbhijitNandy

  • Rank
    Member
  1. Thats what I do too. I generate a triangle mesh covering a small number of latitudes and longitudes (in fact in radian measure its something like 0.000024f rads wide and long). I recreate the mesh and insert it into the bullet dynamics world each time the object it supports move beyond the edges(otherwise the object supported will fall off)
  2. ok, so finally this is what I am using : [CODE] btMatrix3x3 m_el = trans.getBasis(); ry = btAtan2( m_el[0].z(), m_el[0].x() ); if(ry < 0) ry += SIMD_PI; float yaw, pitch, roll; trans.getBasis().getEulerYPR(yaw, pitch, roll); rz = yaw; if(rz < 0) rz += SIMD_PI; rx = roll; if(rx < 0) rx += SIMD_PI; [/CODE] So I apply the rotations in the order Z-Y-X I am getting good rotations for half a turn an there is a wierd turn. I think I may have the order of the rotations wrong. Is this the correct order of rotation ? [media]http://www.youtube.com/watch?v=XCT9ERCwY1s[/media] ----------- Well I tried all 6 combinations, only ZYX and YXZ seems to give somewhat reasonable results for 1 half turn. The mesh then suddenly seems to flip over for the rest of the turn.
  3. Thanks, I will try it out now. Well Bullet does give me orientation as a btmatrix3x3, so I will use the rotation matrix (its apparently called a 'basis') with your method above. The matrices are in openGL form, so the 3 columns contain the 3 axes x, y,z. Here is how getEulerYPR() was implemented by Bullet autthor : [url="http://bulletphysics.com/Bullet/BulletFull/btMatrix3x3_8h_source.html#l00279"]http://bulletphysics...rce.html#l00279[/url] [code] /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR * @param yaw Yaw around Y axis * @param pitch Pitch around X axis * @param roll around Z axis */ void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const { // first use the normal calculus yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); pitch = btScalar(btAsin(-m_el[2].x())); roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); // on pitch = +/-HalfPI if (btFabs(pitch)==SIMD_HALF_PI) { if (yaw>0) yaw-=SIMD_PI; else yaw+=SIMD_PI; if (roll>0) roll-=SIMD_PI; else roll+=SIMD_PI; } }; [/code] Do you think the matrix format is same as the one in your code. You may be using a transposed version of what is used in the above code. Here is how bullet forms the standard openGL submatrix, which may help decide : [code] /**@brief Fill the rotational part of an OpenGL matrix and clear the shear/perspective * @param m The array to be filled */ void getOpenGLSubMatrix(btScalar *m) const { m[0] = btScalar(m_el[0].x()); m[1] = btScalar(m_el[1].x()); m[2] = btScalar(m_el[2].x()); m[3] = btScalar(0.0); m[4] = btScalar(m_el[0].y()); m[5] = btScalar(m_el[1].y()); m[6] = btScalar(m_el[2].y()); m[7] = btScalar(0.0); m[8] = btScalar(m_el[0].z()); m[9] = btScalar(m_el[1].z()); m[10] = btScalar(m_el[2].z()); m[11] = btScalar(0.0); } [/code] I think its as : X Y Z Origin (not included in btMatrix3x3) 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15 So your calculation for Y rotation is equivalent to : [CODE]yaw = btAtan2( m_el[0].z(), m_el[0].x() );[/CODE] --------------- Oh wow...that does work ! Its like magic [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img] : [CODE]btMatrix3x3 m_el = trans.getBasis(); ry = btAtan2( m_el[0].z(), m_el[0].x() ); if(ry < 0) ry += SIMD_PI;[/CODE] so are the other 2 angles - about the z axis and the x axis, also calculated differently from the default code in getEulerYPR() ? Is there a chance of a gimbal lock ?
  4. Yeah you are right, it is the pitch. Though I am not sure why a Y-axis rotation appears in pitch and not yaw. This is the code I use now for getting the angle : [code] trans.getBasis().getEulerYPR(yaw, pitch, roll); pitch = (pitch >= 0) ? pitch : (PI2 + pitch); [/code] Here are some angle values : [CODE] Previous Angle(used to undo) | Modified Pitch | Bullet(Yaw, pitch, roll) | Angle applied to rotate body manually 0.00000 | 5.00000 | (0.00000, 5.00000, 0.00000) | 5.00000 -5.00000 | 10.00000 | (0.00000, 10.00000, 0.00000) | 10.00000 -10.00000 | 15.00000 | (0.00000, 15.00000, 0.00000) | 15.00000 -15.00000 | 20.00000 | (0.00000, 20.00000, 0.00000) | 20.00000 -20.00000 | 25.00000 | (0.00000, 25.00000, 0.00000) | 25.00000 -25.00000 | 30.00000 | (0.00000, 30.00000, 0.00000) | 30.00000 -30.00000 | 35.00000 | (0.00000, 35.00000, 0.00000) | 35.00000 -35.00000 | 40.00000 | (0.00000, 40.00000, 0.00000) | 40.00000 -40.00000 | 45.00000 | (0.00000, 45.00000, 0.00000) | 45.00000 -45.00000 | 50.00000 | (0.00000, 50.00000, 0.00000) | 50.00000 -50.00000 | 55.00000 | (0.00000, 55.00000, 0.00000) | 55.00000 -55.00000 | 59.99999 | (0.00000, 59.99999, 0.00000) | 59.99999 -59.99999 | 64.99999 | (0.00000, 64.99999, 0.00000) | 64.99999 -64.99999 | 70.00001 | (0.00000, 70.00001, 0.00000) | 69.99999 -70.00001 | 74.99999 | (0.00000, 74.99999, 0.00000) | 74.99999 -74.99999 | 80.00001 | (0.00000, 80.00001, 0.00000) | 79.99999 -80.00001 | 85.00002 | (0.00000, 85.00002, 0.00000) | 84.99999 <------------------ increasing -85.00002 | 89.98022 | (0.00000, 89.98022, 0.00000) | 89.99999 <------------------ decreasing -89.98022 | 85.00002 | (180.00001, 85.00002, 180.00001) | 94.99999 <------------------ decreasing -85.00002 | 80.00001 | (180.00001, 80.00001, 180.00001) | 99.99999 -80.00001 | 75.00003 | (180.00001, 75.00003, 180.00001) | 104.99999 -75.00003 | 70.00001 | (180.00001, 70.00001, 180.00001) | 109.99998 -70.00001 | 65.00001 | (180.00001, 65.00001, 180.00001) | 114.99999 -65.00001 | 59.99999 | (180.00001, 59.99999, 180.00001) | 119.99999 -59.99999 | 55.00001 | (180.00001, 55.00001, 180.00001) | 124.99999 -55.00001 | 50.00001 | (180.00001, 50.00001, 180.00001) | 129.99999 -50.00001 | 45.00001 | (180.00001, 45.00001, 180.00001) | 134.99999 -45.00001 | 40.00002 | (180.00001, 40.00002, 180.00001) | 139.99999 -40.00002 | 35.00001 | (180.00001, 35.00001, 180.00001) | 144.99998 -35.00001 | 30.00002 | (180.00001, 30.00002, 180.00001) | 149.99998 -30.00002 | 25.00002 | (180.00001, 25.00002, 180.00001) | 154.99998 -25.00002 | 20.00002 | (180.00001, 20.00002, 180.00001) | 159.99998 -20.00002 | 15.00002 | (180.00001, 15.00002, 180.00001) | 164.99998 -15.00002 | 10.00002 | (180.00001, 10.00002, 180.00001) | 169.99998 -10.00002 | 5.00002 | (180.00001, 5.00002, 180.00001) | 174.99998 -5.00002 | 0.00002 | (180.00001, 0.00002, 180.00001) | 179.99998 -0.00002 | 355.00001 | (180.00001, -4.99998, 180.00001) | 184.99998 -355.00001 | 350.00001 | (180.00001, -9.99998, 180.00001) | 189.99998 -350.00001 | 345.00001 | (180.00001, -14.99997, 180.00001) | 194.99997 -345.00001 | 340.00001 | (180.00001, -19.99997, 180.00001) | 199.99997 -340.00001 | 335.00002 | (180.00001, -24.99997, 180.00001) | 204.99997 -335.00002 | 330.00002 | (180.00001, -29.99997, 180.00001) | 209.99997 -330.00002 | 325.00004 | (180.00001, -34.99997, 180.00001) | 214.99997 -325.00004 | 320.00002 | (180.00001, -39.99997, 180.00001) | 219.99997 -320.00002 | 315.00002 | (180.00001, -44.99997, 180.00001) | 224.99997 -315.00002 | 310.00002 | (180.00001, -49.99998, 180.00001) | 229.99998 -310.00002 | 305.00002 | (180.00001, -54.99998, 180.00001) | 234.99998 -305.00002 | 300.00002 | (180.00001, -59.99998, 180.00001) | 239.99998 -300.00002 | 295.00002 | (180.00001, -64.99998, 180.00001) | 244.99998 -295.00002 | 290.00002 | (180.00001, -69.99998, 180.00001) | 249.99998 -290.00002 | 285.00000 | (180.00001, -75.00000, 180.00001) | 254.99998 -285.00000 | 280.00000 | (180.00001, -80.00001, 180.00001) | 259.99998 -280.00000 | 275.00003 | (180.00001, -84.99998, 180.00001) | 264.99997 -275.00003 | 270.00000 | (0.00000, -90.00000, 0.00000) | 269.99997 -270.00000 | 274.99997 | (0.00000, -85.00002, 0.00000) | 274.99997 -274.99997 | 279.99997 | (0.00000, -80.00003, 0.00000) | 279.99997 -279.99997 | 284.99997 | (0.00000, -75.00003, 0.00000) | 284.99997 -284.99997 | 289.99997 | (0.00000, -70.00004, 0.00000) | 289.99997 -289.99997 | 294.99997 | (0.00000, -65.00003, 0.00000) | 294.99997 -294.99997 | 299.99997 | (0.00000, -60.00003, 0.00000) | 299.99997 -299.99997 | 304.99997 | (0.00000, -55.00003, 0.00000) | 304.99997 -304.99997 | 309.99997 | (0.00000, -50.00004, 0.00000) | 309.99997 -309.99997 | 314.99996 | (0.00000, -45.00004, 0.00000) | 314.99996 -314.99996 | 319.99996 | (0.00000, -40.00004, 0.00000) | 319.99996 -319.99996 | 324.99996 | (0.00000, -35.00004, 0.00000) | 324.99996 -324.99996 | 329.99996 | (0.00000, -30.00004, 0.00000) | 329.99996 -329.99996 | 334.99996 | (0.00000, -25.00004, 0.00000) | 334.99996 -334.99996 | 339.99996 | (0.00000, -20.00004, 0.00000) | 339.99996 -339.99996 | 344.99996 | (0.00000, -15.00004, 0.00000) | 344.99996 -344.99996 | 349.99996 | (0.00000, -10.00004, 0.00000) | 349.99996 -349.99996 | 354.99996 | (0.00000, -5.00004, 0.00000) | 354.99996 -354.99996 | 359.99996 | (0.00000, -0.00004, 0.00000) | 359.99996 -359.99996 | -0.00000 | (0.00000, -0.00000, 0.00000) | 0.00000 0.00000 | 5.00000 | (0.00000, 5.00000, 0.00000) | 5.00000 [/CODE] The Bullet values are in the fat middle column. The problem lies in the sudden decrease in the angle values as we cross 90 degrees. This causes my mesh to rotate backwards after 1/4th turn.
  5. Hi, Is it possible to convert the yaw Euler angle got from the Bullet physis engine using btTransform trans; trans.getBasis().getEulerYPR(rx, ry, rz); into the range [0 , 360]. Otherwise for a 360 deg rotation I get the Euler angle varying from 0->90->0-> -90 -> 0 but I want from 0->90->180->270->0 My graphics API only accepts rotation angles in the range of 0 to 360
  6. So till something better comes up, I ll continue to flesh out my idea here for my limited simple purposes. If anyone has got suggestions please do let me know. My Lunar base will be set up something like as follows: [img]http://img10.imageshack.us/img10/7553/basetv.png[/img] So it will be in 3D but lets stick to a 2d view for now. The entire area is divided up into sections. Each sections can have rooms. The sections S2 has 4 rooms. The remaining area is outside. I would store this as an adjacency graph as follows : [img]http://img37.imageshack.us/img37/3245/33610317.png[/img] This is basically space partitioning though not like a BSP. Each node stores its bounding box in space and there is an out node always for the "rest" of the area in a section that is not covered by rooms. We can get which room the camera is located in , at the start of the game, in O(log N) time as its a tree. However we also need to store adjacency information, so we add links to adjacent rooms : [img]http://img269.imageshack.us/img269/9606/modag.png[/img] This helps us decide which rooms to load when the camera position has been found in the tree. We simply load all adjacent rooms for now. But how about using the graph to support level of detail as well. We dont want hi-res textures and meshes for rooms to be loaded if they are really far away from the camera. To support it we have each node maintain its distance from camera. Now suppose the user is in R3 and decides to go left to section S1(so he is not only changing rooms but sections as well), then we have the : leaving node R3 and the entering node S1 Operations initiated for the leaving node : For every leaving node, we tell all adjacent nodes to update their camera distances. R1 may find its quite far away from the camera now, so it loads a lower detail mesh for itself. R2 and R4 are no longer visible as they are not in the visible set of rooms/sections for S1. They decide to unload themselves. Whenever a rooms unloads itself it tells its parent that its unloaded itself. A bitmask in the parent is updated to reflect the fact(as shown below S4). 1 means loaded, 0 means unloaded. After all adjacent nodes are updated we go to the parent node of the leaving node(in this case S2 and repeat). The parent may find that its bit mask == 0, so it can unload itself. Or some additional conditions can be set. If the camera has moved out of the base and far from it, then all meshes for the base are removed !. If some rooms are in the visible set of the entering node then they can still check the camera positions and load lower res textures/meshes if needed. R3 also updates its own meshes based on the camera distance. Operations for the entering node: Here it may be possible to go lower down the node S1 to decide which room the camera is in(if S1 has rooms). I decided that if S1 has rooms then the pointer from R3 will directly point to the adjacent rooms instead of to the parent section S1 (for speed). We simply check all nodes adjacent to S1 and all children of S1(if any) and load them. When the nodes load they will check the camera position and load approporiate low res/high res meshes. We skip the node we just came from i.e. R3 as its already updated itself and any nodes adjacent to it. What each node must contain : All this means the nodes have to track their own meshes and loaded state. Camera distance need only be updated when the node is told to update itself. The node must also maintain a pointer to its only parent and a list of pointers to its adjacent rooms/sections. It must maintain a bitmap to track which of its children are loaded and if it can unload itself. Bounds checking: Bounds checking will probably be a bottleneck here especially due to irregularly shaped rooms, Each node can maintain a list of shapes which overlap in some places, to define the room. So all the shapes are checked against. to decide if the camera is in the room...kind of like clipping shapes. Also I havent gone down to the level of loading/unloading objects [i]inside [/i]the room yet, but this can probably be added by adding another level to the tree. I will construct the graph while the objects in the rooms ..and the rooms themselves are being laid out in blender or max or whatever.
  7. Hmmm, in the above paper they seems to have used adjacency graphs with the cells being the nodes and the links between cells being the portals(or openings/doors). See section 3. Creating Frontier Sets Has some pseudo code to generate the PVS. It will probably be a good starting point.
  8. ok , well here is some more info about my specfic case. I am developing a plugin for a space flight simulator called as Orbiter : http://orbit.medphys.ucl.ac.uk/ It allows creation of spacecraft, bases etc and has an extensive API. It already provides a directx based viewer, functions for loading meshes etc. A lot of the low level stuff is already automated such as texture loading which happens along with the meshes, occlusions culling etc. So I would probably not need to go down to the polygon level. Any help to the CPU in terms of unloading meshes which are not visible to the camera would help while exploring the inside of large vessels. I have decided to integrate Bullet Physics with Orbiter and it actually works quite well. I have got a rover traversing Lunar terrain now : http://code.google.com/p/surface-physics/ What I will be doing with the PVS is tracking large sections of a base or vessel and loading and unloading the sections based on the distance of the camera from a section.I ll need to load the graphics stuff and the physics stuff together of course so collisions happen based on whats visible. I am currently goin through the concept of PVS as discussed here : https://docs.google.com/viewer?a=v&q=cache:sH7_Z8XIlzAJ:www.cs.ucl.ac.uk/staff/ucacajs/frontiers_shortlow.pdf+example+Potentially+Visible+Sets&hl=en&gl=us&pid=bl&srcid=ADGEEShcyvQ2_8sLXFH9WrbNtvvbXp-Ef4MF6OPc6lBtx6Nh3yROUwk0pNqTjn7cVASl9erVOxoljp5zuZysG9OTFfXNXUJWf-wuwvy3qDb1NPQG153Y-tgVLEQ9I0Lft2xOjGbMb4es&sig=AHIEtbSjGYnyXDdAO19JNnM7LkOGC2h2Sg
  9. Good going L. Spriro. Looking forward to your tutorial on BSP trees. Since you seem to have done similar stuff, I am wondering if my approach is in any way close to an efficent solution
  10. Hi, I want to create complex scenes in my 3D application. Like a house with rooms in it and stuff inside the rooms. I want to remove rooms which are not visible in the camera. I know opengl will clip stuff that are not visible, but I am talking about not sending the data about rooms and objects which are blocked, at all. So I have heard that for complex scenes a scene grah can help. But most implementation of scene graphs seem to take a hierarchical view of the scene. Say we have a city which is the root node, then the buildings would be its children and the rooms in the buildings would be lower level chidlren etc. This structure does not help in knowing which rooms are adjacent to each other(all adjacent rooms are children of the same parent node). I came up with this idea for a scene graph where the links between nodes represent the "is adjacent" relationship and the nodes are objects : [url="http://imageshack.us/photo/my-images/864/scgp.png/"][img]http://img864.imageshack.us/img864/7968/scgp.png[/img][/url] The lower part of this picture was added later, please ignore it.for now. So here we have irregularly shaped rooms. The camera is at the position shown by the red dot. The bounding box(BB) of D is the red border square. As long as the camera is in the red square, the 3D and physics data for B, C & A is loaded. Of course D is there also. But when it moves out of the box to say A, then B & C is unloaded. Also the camera is marked to be "in" A right now. This saves on texture memory and mesh calls to the graphics API. However a tricky issue is, in a huge graph with many rooms, if I am given a camera position, then I would need to find its owning room by going through all the nodes in the graph which may be prohibitive. Any objects inside the room D is considered to be adjacent to it as well.If an object is carried outside the room, well then the links are changed to reflect the object's new spatial position with respect to the rooms. Has anyone got a better suggestion on how to solve this ? Are there open source libraries out there which can do it faster. Especially if I have a camera position and I want to get to the node to which it belongs(is closest to) ? ---------------- The other option as shown in the lower part of the picture, is to combine a hierarchical volume graph and an adjacency graph into one. So we start with a hierarchical graph as shown in the lower part of the image where the root is A and A's children are inside the volume of A. Now if I want to find in which volume the camera is located I can do so in logarithmic time. However each node(like C) also maintains links to volumes adjacent to it. So I can find and load only adjacent rooms and not the whole darn house ! what do you guys think ?
  11. Agni V can be directed towards twitter and Facebook HQ's if required :- kapil sibal
  12. Long story short, I have 2 static planes. One at (0,0,0) and another at (0, 500, 0). I instantiate a btRayCastVehicle at (0, 10, 0), so above the lower plane. There is no other force or body in the world. The vehicle shoots straight up and keeps on going !! There is absolutely no reason for this to happen. Reproduction code included. If I replace the planes with btBoxShape, then this doesnt happen. But I want to use 2 planes above each other and parallel to each other. If I place the planes closer to each other, say 50 units, then the vehicle (or in fact any other box), shoots up slower, but shoots up nevertheless. I cant understand how the position of 2 static planes can affect the position of a dynamic rigid body like a box when there are no other forces in the world at all, and no intervention from the user.
  13. Sorry got double posted, please remove this [img]http://public.gamedev.net//public/style_emoticons/default/sad.png[/img]
  14. I am trying to render a car using OpenGL. The car has a chassis and 4 wheels. The chassis is simply a cuboid and the wheels are cylinders. I have their positions from the Bullet physics engine as openGL matrices. If I pass these matrices to glMultMatrixf() in turn and push and pop matrices correctly then I do get the car rendered correctly as it moves around. [code] //Render Ground Plane------------------------------- float PLANE_EXTENT = 100.0f; glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f(-PLANE_EXTENT, 0.0f, -PLANE_EXTENT); // Top Left Of The Texture and Quad glTexCoord2f(0.0f, 0.0f); glVertex3f(-PLANE_EXTENT, 0.0f, PLANE_EXTENT); // Bottom Left Of The Texture and Quad glTexCoord2f(1.0f, 0.0f); glVertex3f( PLANE_EXTENT, 0.0f, PLANE_EXTENT); // Bottom Right Of The Texture and Quad glTexCoord2f(1.0f, 1.0f); glVertex3f( PLANE_EXTENT, 0.0f, -PLANE_EXTENT); // Top Right Of The Texture and Quad glEnd(); glColor3f(1.0,0,0); //Render Chassis----------------------------------- glPushMatrix(); glMultMatrixf(ptrShapes->m); glMultMatrixf(ptrShapes->childMat); drawBox(ptrShapes->halfExtent[0], ptrShapes->halfExtent[1], ptrShapes->halfExtent[2]); glPopMatrix(); //Render the obstructing green box glColor3f(0.0,1.0,0.0); glPushMatrix(); glMultMatrixf(ptrShapes->m_box); drawBox(ptrShapes->box_halfExtent[0], ptrShapes->box_halfExtent[1], ptrShapes->box_halfExtent[2]); printf("\n box : %f, %f,%f", ptrShapes->box_halfExtent[0], ptrShapes->box_halfExtent[1], ptrShapes->box_halfExtent[2]); glPopMatrix(); //Render the 4 wheels glColor3f(1.0,1.0,0); for (int i=0; i<4; i++){ glPushMatrix(); switch(i){ case 0 : glMultMatrixf(ptrShapes->m1);break; case 1 : glMultMatrixf(ptrShapes->m2);break; case 2 : glMultMatrixf(ptrShapes->m3);break; case 3 : glMultMatrixf(ptrShapes->m4);break; } drawCylinder(ptrShapes->radius, ptrShapes->halfHeight, ptrShapes->upAxis); printf("\n r : %f ht:%f", ptrShapes->radius, ptrShapes->halfHeight); glPopMatrix(); } //---------------Debug code : for pink wheel----------------------- glColor3f(1.0,0.0,1.0); glPushMatrix(); glMultMatrixf(ptrShapes->m); glTranslatef(ptrShapes->m2[12] - ptrShapes->m[12], ptrShapes->m2[13] - ptrShapes->m[13], ptrShapes->m2[14] - ptrShapes->m[14]); drawCylinder(ptrShapes->radius, ptrShapes->halfHeight, ptrShapes->upAxis); glPopMatrix(); [/code] Now I am trying something different. I am trying to render one of the wheels without using glMultMatrixf(). So given the transformation matrix I am trying to simply translate the wheel into position(not bothered about orienting it at the moment). The code marked as //----debug code----- in the bottom shows this part. So what I have is the wheel transformation matrices in the matrices m1, m2, m3, m4. I chose one of the wheels(forward left wheel) whose matrix is in m2 and tried to use the translation elements of the matrix to translate the wheel into position. But it does not work as expected and there is a difference in the mesh positions between the wheel rendered through glMultMatrixf() and that rendered through glTranslatef(). I used the following to understand the opengl matrix format : [img]http://www.songho.ca/opengl/files/gl_anglestoaxes01.png[/img] The reason I subtract ptrShapes->m[...] from the respective x,y,z positions is because I have already translated to the position given by it using glMultMatrixf(). The postion given by m is the global position of the vehicle. Here is a video of the thing : [url="http://www.youtube.com/watch?v=0iATE7MVTkE"]http://www.youtube.c...h?v=0iATE7MVTkE[/url] Also if I dont subtract m and directly render the wheel using m2 then I get the desired effect. Here is the code [code] //---------Debug code------------ glColor3f(1.0,0.0,1.0); glPushMatrix(); glTranslatef(ptrShapes->m2[12] , ptrShapes->m2[13], ptrShapes->m2[14] ); drawCylinder(ptrShapes->radius, ptrShapes->halfHeight, ptrShapes->upAxis); glPopMatrix(); [/code] Video : [url="http://www.youtube.com/watch?v=E0hyQjclx58"]http://www.youtube.c...h?v=E0hyQjclx58[/url] Now I cannot understand why the 2 don't match. If I have already translated to the proper vehicle position using m then if I render the wheel at [b]the translated position with respect to the vehicle(by subtracting the translation elements of m from the translation elements of m2)[/b] I should get the same position. Obviously the rotations around the axes do not make a difference here as then I would not have got the right position by rendering at m2 directly. I need to render the wheels using their positions with respect to the main vehicle(whose co-ordinates are in m) due to some restrictions in the API of the Orbiter Space flight simulation software in which I am trying to integrate the vehicle. Long story short...I can only render the wheel with respect to the vehicle(whose world space coordinates are in m). So I need to get the correct co-ordinates fo the wheel with respect to the vehicle after I have been given the world space co-ordinates of both the wheel(in m2) and the vehicle(in m)