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

Generated on Fri May 16 08:34:01 2008 for SecondLife by  doxygen 1.5.5