Archived

This topic is now archived and is closed to further replies.

Rotate Normal about Itself

This topic is 6360 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, Quick problem, which i can''t seem to figure out. I need to rotate a NORMAL vector about it''s own axis, if you see what i mean. Say i have a cube, the face with the normal of 0,0,1 I would need to rotate 90 degrees around the world Y Axis, and for the Top face of the cube, with a normal of 0,1,0 I would need to rotate around the World Z Axis for the normals to be rotated in the same way. So basically i need to rotate each normal about it''s own Y Axis, but i can''t figure it. Obviously it''s easy if we are always using cubes, which always have normals of 0''s and 1''s but the faces could be at any angle =) Any help is greatly appreciated, i realise that was a crap explanation (i always have trouble explaining what i need help with =) so if you need me to try and re-write my problem, just ask, heh. Thanks Adam "Nutz" Hoult VB Gaming Central

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well, without a second vector to call "up" or "left" what you want is impossible since there are infinite vectors which you could call its "y-axis".

Share this post


Link to post
Share on other sites
I understand what you are saying, but by the very essence of the normal, in effect the way the normal vector is pointing, is it's own Z Axis

i.e If i was right in front of a face, then the normal would be pointing towards me along the cameraspace Z axis, so we at least have a definition of the planes axies (
Imagine this, The face is a rectangle, directly in front of me, the face normal is pointing along the Z axis, now i want to rotate the face normal 90 degrees around the normals Y axis

This VERY badly drawn ascii diagram should show what i mean, it shows the axis direction for two faces, remember the Z axis always points along the normal direction, and my real world UP vector is (0,1,0).

        
^
---|--/------
/ Z| /Y / |
/ |/ / |
/ ---X / |
------------ |
| ^ | |
| |Y | |
| | X | /
| /---->| /
| Z/ | /
-----/--------



Thanks again



Adam "Nutz" Hoult
VB Gaming Central

Edited by - daedalusd on July 13, 2000 6:01:11 PM

Share this post


Link to post
Share on other sites
Maybe i'm going about it wrong then, all i need to know, is given a face normal, or a set of vertices, i need a normalized direction vector from the left most point of the polygon to the right most point, and another from topmost to the bottom most point. (they have to be in a straight line i.e like the diagram below. I need the Real World Vector.

This is why, since i know the normal direction will always be pointing straight out from the polygon, then if i just rotate the normal to the right 90 degrees, i have Direction Vector 1, and if i rotate the normal 90 degrees downwards, i have direction vector 2, see my reasoning ??

        
o-----x Direction Vector 1 ;
|\ ;
| \ ;
| \ ;
| \ ;
|____\ ;
x ;
Direction Vector 2 ;



Hope this makes sense.

Adam "Nutz" Hoult
VB Gaming Central

Edited by - daedalusd on July 13, 2000 6:19:28 PM

Share this post


Link to post
Share on other sites
I''m still not 100% sure what you''re asking.

I think that you''re asking for a set of X, Y, and Z axies such that Z is perpendicular to the plane, and X and Y are both along the plane such that they are perpendicular to each other and X is perpendicular to the world''s Y axis (0, 1, 0) Is this right?

If so, you use the old "multiple cross-product" trick. First normalize the normal vector. Then cross (0, 1, 0) (the world''s "Up" vector) with that vector to find a vector perpendicular to both the normal and the global "Up" axis. Normalize this new vector to get the X axis. Finally, cross the normal with X to get the actual Y axis.

...Syzygy

Share this post


Link to post
Share on other sites
Hmm, i've tried both your suggestions (thanks for helping btw), but neither work correctly.

Perhaps if i just say what I am trying to do.

Basically I am trying to generate texture coordinates for each face based on the world position of the vertex. If anyone has used worldcraft or any other editor for quake/half-life levels, textures are applied depending on their position in the world, this makes seamless texturing easier for the world designer (as each objects texture will be aligned correctly automatically)

The formula I have for setting the texture coords from the output from worldcraft is (x, y and z are the Vertex X/Y/Z coords)

        
u = x * u_axis.x + y * u_axis.y + z * u_axis.z + u_offset;
v = x * v_axis.x + y * v_axis.y + z * v_axis.z + v_offset;


This works fine if i'm just loading in a BSP file from world craft (i.e the textures are all correctly positioned), but my problem is that I am trying to figure out the u_axis and v_axis values, it seemed that they were just the face normal rotated 90 degrees to the right (for u_axis) and 90 degrees downwards for the v_axis vector. After thinking about it in great detail (2 days i've been trying to do this), i'm no further on. (FYI: Im writing a world editor for my engine similar to worldcraft, and this is one feature on my MUST HAVE list which is why im spending so much time on it =)

So in a last ditch attempt to see if anyone has a solution, i'll see if anyone can throw up any suggestions of how to do this, rather than asking for you guys to help me work on my half-baked solutions

Thanks for all your help so far.




Adam "Nutz" Hoult
VB Gaming Central

Edited by - daedalusd on July 14, 2000 10:00:44 AM

Share this post


Link to post
Share on other sites
What you need in addition to the normal is a vector in the plane of the polygon. Use this vector to set the u coordinate and take the crossproduct of the vector and the normal to get an axis for the v coordinate.

The vector in the plane can be aquired in a multitude of ways. One way is to take one of the polygons edges and normalize it. Another way is to project one of the world axis onto the polygon and renormalize. My suggestion to you is to use a projected world axis as it is easier to align textures on parallell polygons that way (you get it for free).

If you need more explanation then I could maybe dig up the old source code for my own 3D editor where I have solved this problem. I would rather you solve it yourself, but if you ask really nice...

- WitchLord

Share this post


Link to post
Share on other sites
Thanks for the help WitchLord (as always), i know what your saying, and i personally prefer to figure things out myself if I can, but i''ve tried using the techniques you mentioned, and it just completely screws up You know how when you are trying to fix a problem for days, and you end up repeating things you''ve already tried ? Well i''m on the 6th time round them all i think If you could find it in your heart to provide a bit of source which I can disect and implement, i don''t want to completely rip it off, just to understand how it works for future use.

Thanks in advance



Adam "Nutz" Hoult
VB Gaming Central

Share this post


Link to post
Share on other sites
Ok, here''s some code. It''s a few years old so I would probably not do it like this today but it worked then, and it should work for you too.

    
void CFlatSurface::SetTextureData(CTextureContainer *pTexture, float fWidth, float fHeight, float fU, float fV, float fRotate, float fSkew)
{
D3DMATRIX dmtxRotate;
D3DVECTOR dvecUPrim, dvecVPrim;
D3DVECTOR *pdvecVertex;

if( m_pTextureContainer )
m_pTextureContainer->Release();

m_pTextureContainer = pTexture;

if( m_pTextureContainer )
{
m_pTextureContainer->Acquire();
m_bTextureApplied = TRUE;
}
else
{
m_bTextureApplied = FALSE;
return;
}

m_fTextureWidth = fWidth;
m_fTextureHeight = fHeight;

// Get the coordinate axises of the plane

if( fabs(m_dvecNormal.dvY) < (float)sqrt(0.5) )
{
// A vertical plane (almost)
m_dvecTextureUAxis = Normalize(CrossProduct(m_dvecNormal,Vector(0,1,0)));
m_dvecTextureVAxis = Normalize(CrossProduct(m_dvecNormal,m_dvecTextureUAxis));
}
else
{
// A horizontal plane

m_dvecTextureUAxis = Normalize(CrossProduct(m_dvecNormal,Vector(0,0,1)));
m_dvecTextureVAxis = Normalize(CrossProduct(m_dvecNormal,m_dvecTextureUAxis));
}

// Rotate the axises

dmtxRotate = RotationMatrix(m_dvecNormal, fRotate);
VectorMatrixMultiply(m_dvecTextureUAxis, m_dvecTextureUAxis, dmtxRotate);
VectorMatrixMultiply(m_dvecTextureVAxis, m_dvecTextureVAxis, dmtxRotate);

// Skew them

dmtxRotate = RotationMatrix(m_dvecNormal, fSkew);
VectorMatrixMultiply(m_dvecTextureUAxis, m_dvecTextureUAxis, dmtxRotate);

m_dvecTextureOrigo = Vector(0,0,0);
m_dvecTextureOrigo = m_dvecTextureOrigo - fU * (m_fTextureWidth*m_pTextureContainer->GetWidth()/g_wTextureSize) * m_dvecTextureUAxis;
m_dvecTextureOrigo = m_dvecTextureOrigo - fV * (m_fTextureHeight*m_pTextureContainer->GetHeight()/g_wTextureSize) * m_dvecTextureVAxis;

dvecUPrim = m_dvecTextureUAxis - DotProduct(m_dvecTextureUAxis, m_dvecTextureVAxis) * m_dvecTextureVAxis;
dvecVPrim = m_dvecTextureVAxis - DotProduct(m_dvecTextureVAxis, m_dvecTextureUAxis) * m_dvecTextureUAxis;

// Compute the texturecoordinates

pdvecVertex = m_pShell->GetVertexList();
for( int n = 0; n < m_iIndexCount; n++ )
{
m_pvtxIndex[n].fTU = DotProduct(pdvecVertex[m_pvtxIndex[n].wIndex]-m_dvecTextureOrigo,dvecUPrim)/
(dvecUPrim.dvX*dvecUPrim.dvX+dvecUPrim.dvY*dvecUPrim.dvY+dvecUPrim.dvZ*dvecUPrim.dvZ)/
(m_fTextureWidth*m_pTextureContainer->GetWidth()/g_wTextureSize);
m_pvtxIndex[n].fTV = DotProduct(pdvecVertex[m_pvtxIndex[n].wIndex]-m_dvecTextureOrigo,dvecVPrim)/
(dvecVPrim.dvX*dvecVPrim.dvX+dvecVPrim.dvY*dvecVPrim.dvY+dvecVPrim.dvZ*dvecVPrim.dvZ)/
(m_fTextureHeight*m_pTextureContainer->GetHeight()/g_wTextureSize);
}
}


- WitchLord

Share this post


Link to post
Share on other sites
Thats it !!! I already had this !!, Syzygy mentioned the method earlier, the only thing which it didn''t have was the if (fabs(FNormal.y) < (float)sqrt(0.5)) etc, thank you both (credit where credits due, Syzygy did hit the nail on the head, but i didn''t figure i had to do the extra bit) and Especially witchlord, I can finally get on with the rest of my LIFE !! =)

Thanks, i''m forever in your debt hehehe .


Adam "Nutz" Hoult
VB Gaming Central

Share this post


Link to post
Share on other sites