llsprite.cpp

Go to the documentation of this file.
00001 
00032 /* -*- c++ -*-
00033  *      Notes:
00034  *              PR - Should add a creator that can take a pointer rather than handle for streaming 
00035  *              object textures.
00036  *              PR - Need to add support for lit/non-lit conditions, set normals?
00037  */
00038 
00039 #include "llviewerprecompiledheaders.h"
00040 
00041 #include <llglheaders.h>
00042 
00043 #include "llsprite.h"
00044 
00045 #include "math.h"
00046 
00047 #include "lldrawable.h"
00048 #include "llface.h"
00049 #include "llviewercamera.h"
00050 #include "llviewerimagelist.h"
00051 #include "viewer.h"
00052 
00053 LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f);
00054 LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f);
00055 LLVector3 LLSprite::sCameraPosition(0.f, 0.f, 0.f);
00056 LLVector3 LLSprite::sNormal(0.0f,0.0f,0.0f);
00057 
00059 // Construction/Destruction
00061 
00062 // A simple initialization
00063 LLSprite::LLSprite(const LLUUID &image_uuid)
00064 {
00065         mImageID = image_uuid;
00066         mImagep = NULL;
00067 
00068         setSize(1.0f, 1.0f);
00069         setPosition(LLVector3(0.0f, 0.0f, 0.0f));
00070         mTexMode = GL_REPLACE;
00071         mColor.setVec(0.5f, 0.5f, 0.5f, 1.0f);
00072         mFollow = TRUE;
00073         mUseCameraUp = TRUE;
00074 }
00075 
00076 LLSprite::LLSprite(const LLUUID &image_uuid, const F32 width, const F32 height, const BOOL b_usemipmap)
00077 {
00078         mImageID = image_uuid;
00079         mImagep = NULL;
00080 
00081         setSize(width,height);
00082         setPosition(LLVector3(0.0f, 0.0f, 0.0f));
00083         mTexMode = GL_REPLACE;
00084         mColor.setVec(0.5f, 0.5f, 0.5f, 1.0f);
00085         mFollow = TRUE;
00086         mUseCameraUp = TRUE;
00087 }
00088 
00090 LLSprite::~LLSprite()
00091 {
00092 }
00093 
00094 void LLSprite::updateFace(LLFace &face)
00095 {
00096         LLViewerCamera &camera = *gCamera;
00097 
00098         // First, figure out how many vertices/indices we need.
00099         U32 num_vertices, num_indices;
00100         U32 vertex_count = 0;
00101         
00102         // Get the total number of vertices and indices
00103         if (mFollow)
00104         {
00105                 num_vertices = 4;
00106                 num_indices = 6;
00107         }
00108         else
00109         {
00110                 num_vertices = 4;
00111                 num_indices = 12;
00112         }
00113 
00114         face.setSize(num_vertices, num_indices);
00115         
00116         if (mFollow) 
00117         {
00118                 sCameraUp = camera.getUpAxis();
00119                 sCameraRight = -camera.getLeftAxis();
00120                 sCameraPosition = camera.getOrigin();
00121                 sNormal = -camera.getAtAxis();
00122                 if (mUseCameraUp)
00123                 {
00124                         // these need to live here because the height/width may change between render calls
00125                         mScaledUp = sCameraUp;
00126                         mScaledRight = sCameraRight;
00127 
00128                         mScaledUp *= mHeightDiv2;
00129                         mScaledRight *= mWidthDiv2;
00130 
00131                         mA = mPosition + mScaledRight + mScaledUp;
00132                         mB = mPosition - mScaledRight + mScaledUp;
00133                         mC = mPosition - mScaledRight - mScaledUp;
00134                         mD = mPosition + mScaledRight - mScaledUp;
00135                 }
00136                 else
00137                 {
00138                         // The up vector is perpendicular to the camera vector...
00139                         LLVector3 camera_vec = mPosition - sCameraPosition;
00140                         mScaledRight = camera_vec % LLVector3(0.f, 0.f, 1.f);
00141                         mScaledUp = -(camera_vec % mScaledRight);
00142                         mScaledUp.normVec();
00143                         mScaledRight.normVec();
00144                         mScaledUp *= mHeightDiv2;
00145                         mScaledRight *= mWidthDiv2;
00146 
00147                         mA = mPosition + mScaledRight + mScaledUp;
00148                         mB = mPosition - mScaledRight + mScaledUp;
00149                         mC = mPosition - mScaledRight - mScaledUp;
00150                         mD = mPosition + mScaledRight - mScaledUp;
00151                 }
00152         }
00153         else
00154         {
00155                 // this is equivalent to how it was done before. . . 
00156                 // we need to establish a way to 
00157                 // identify the orientation of a particular sprite rather than
00158                 // just banging it in on the x,z plane if it's not following the camera.
00159 
00160                 LLVector3 x_axis;
00161                 LLVector3 y_axis;
00162 
00163                 F32 dot = sNormal * LLVector3(0.f, 1.f, 0.f);
00164                 if (dot == 1.f || dot == -1.f)
00165                 {
00166                         x_axis.setVec(1.f, 0.f, 0.f);
00167                         y_axis.setVec(0.f, 1.f, 0.f);
00168                 }
00169                 else
00170                 {
00171                         x_axis = sNormal % LLVector3(0.f, -1.f, 0.f);
00172                         x_axis.normVec();
00173 
00174                         y_axis = sNormal % x_axis;
00175                 }
00176 
00177                 LLQuaternion yaw_rot(mYaw, sNormal);
00178 
00179                 // rotate axes by specified yaw
00180                 x_axis = x_axis * yaw_rot;
00181                 y_axis = y_axis * yaw_rot;
00182 
00183                 // rescale axes by width and height of sprite
00184                 x_axis = x_axis * mWidthDiv2;
00185                 y_axis = y_axis *  mHeightDiv2;
00186 
00187                 mA = -x_axis + y_axis;
00188                 mB = x_axis + y_axis;
00189                 mC = x_axis - y_axis;
00190                 mD = -x_axis - y_axis;
00191 
00192                 mA += mPosition;
00193                 mB += mPosition;
00194                 mC += mPosition;
00195                 mD += mPosition;
00196         }
00197 
00198         face.setFaceColor(mColor);
00199 
00200         LLStrider<LLVector3> verticesp;
00201         LLStrider<LLVector3> normalsp;
00202         LLStrider<LLVector2> tex_coordsp;
00203         LLStrider<U32> indicesp;
00204         S32 index_offset;
00205 
00206         // Setup face
00207         if (face.mVertexBuffer.isNull())
00208         {       
00209                 face.mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | 
00210                                                                                                 LLVertexBuffer::MAP_TEXCOORD,
00211                                                                                                 GL_STREAM_DRAW_ARB);
00212                 face.mVertexBuffer->allocateBuffer(4, 12, TRUE);
00213                 face.setGeomIndex(0);
00214                 face.setIndicesIndex(0);
00215         }
00216                 
00217         index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp);
00218         if (-1 == index_offset)
00219         {
00220                 return;
00221         }
00222 
00223         *tex_coordsp = LLVector2(0.f, 0.f);
00224         *verticesp = mC;
00225         tex_coordsp++;
00226         verticesp++;
00227         vertex_count++;
00228 
00229         *tex_coordsp = LLVector2(0.f, 1.f);
00230         *verticesp = mB;
00231         tex_coordsp++;
00232         verticesp++;
00233         vertex_count++;
00234 
00235         *tex_coordsp = LLVector2(1.f, 1.f);
00236         *verticesp = mA;
00237         tex_coordsp++;
00238         verticesp++;
00239         vertex_count++;
00240 
00241         *tex_coordsp = LLVector2(1.f, 0.0f);
00242         *verticesp = mD;
00243         tex_coordsp++;
00244         verticesp++;
00245         vertex_count++;
00246 
00247         // Generate indices, since they're easy.
00248         // Just a series of quads.
00249         *indicesp++ = index_offset;
00250         *indicesp++ = 2 + index_offset;
00251         *indicesp++ = 1 + index_offset;
00252 
00253         *indicesp++ = index_offset;
00254         *indicesp++ = 3 + index_offset;
00255         *indicesp++ = 2 + index_offset;
00256 
00257         if (!mFollow)
00258         {
00259                 *indicesp++ = 0 + index_offset;
00260                 *indicesp++ = 1 + index_offset;
00261                 *indicesp++ = 2 + index_offset;
00262                 *indicesp++ = 0 + index_offset;
00263                 *indicesp++ = 2 + index_offset;
00264                 *indicesp++ = 3 + index_offset;
00265         }
00266 
00267         //face.mVertexBuffer->setBuffer(0);
00268         face.mCenterAgent = mPosition;
00269 }
00270 
00271 void LLSprite::setPosition(const LLVector3 &position) 
00272 {
00273         mPosition = position; 
00274 }
00275 
00276 
00277 void LLSprite::setPitch(const F32 pitch) 
00278 {
00279         mPitch = pitch; 
00280 }
00281 
00282 
00283 void LLSprite::setSize(const F32 width, const F32 height) 
00284 {
00285         mWidth = width; 
00286         mHeight = height;
00287         mWidthDiv2 = width/2.0f;
00288         mHeightDiv2 = height/2.0f;
00289 }
00290 
00291 void LLSprite::setYaw(F32 yaw) 
00292 {
00293         mYaw = yaw; 
00294 }
00295 
00296 void LLSprite::setFollow(const BOOL follow)
00297 {
00298         mFollow = follow; 
00299 }
00300 
00301 void LLSprite::setUseCameraUp(const BOOL use_up)
00302 {
00303         mUseCameraUp = use_up; 
00304 }
00305 
00306 void LLSprite::setTexMode(const LLGLenum mode) 
00307 {
00308         mTexMode = mode; 
00309 }
00310 
00311 void LLSprite::setColor(const LLColor4 &color)
00312 {
00313         mColor = color; 
00314 }
00315 
00316 void LLSprite::setColor(const F32 r, const F32 g, const F32 b, const F32 a)
00317 {
00318         mColor.setVec(r, g, b, a);
00319 }
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 

Generated on Thu Jul 1 06:09:12 2010 for Second Life Viewer by  doxygen 1.4.7