PageRenderTime 356ms CodeModel.GetById 51ms app.highlight 254ms RepoModel.GetById 37ms app.codeStats 1ms

/indra/newview/llpolymesh.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1261 lines | 848 code | 167 blank | 246 comment | 131 complexity | fa264e75344f8d8ed76adceb4988e824 MD5 | raw file
   1/** 
   2 * @file llpolymesh.cpp
   3 * @brief Implementation of LLPolyMesh class
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27//-----------------------------------------------------------------------------
  28// Header Files
  29//-----------------------------------------------------------------------------
  30#include "llviewerprecompiledheaders.h"
  31
  32#include "llfasttimer.h"
  33#include "llmemory.h"
  34
  35#include "llviewercontrol.h"
  36#include "llxmltree.h"
  37#include "llvoavatar.h"
  38#include "llwearable.h"
  39#include "lldir.h"
  40#include "llvolume.h"
  41#include "llendianswizzle.h"
  42
  43#include "llpolymesh.h"
  44
  45#define HEADER_ASCII "Linden Mesh 1.0"
  46#define HEADER_BINARY "Linden Binary Mesh 1.0"
  47
  48extern LLControlGroup gSavedSettings;                           // read only
  49
  50LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
  51					     const std::string &name);
  52LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
  53					     const LLVector3 &direction,
  54					     const std::string &name);
  55LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
  56                                            F32 scale,
  57                                            const std::string &name);
  58
  59//-----------------------------------------------------------------------------
  60// Global table of loaded LLPolyMeshes
  61//-----------------------------------------------------------------------------
  62LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
  63
  64//-----------------------------------------------------------------------------
  65// LLPolyMeshSharedData()
  66//-----------------------------------------------------------------------------
  67LLPolyMeshSharedData::LLPolyMeshSharedData()
  68{
  69        mNumVertices = 0;
  70        mBaseCoords = NULL;
  71        mBaseNormals = NULL;
  72        mBaseBinormals = NULL;
  73        mTexCoords = NULL;
  74        mDetailTexCoords = NULL;
  75        mWeights = NULL;
  76        mHasWeights = FALSE;
  77        mHasDetailTexCoords = FALSE;
  78
  79        mNumFaces = 0;
  80        mFaces = NULL;
  81
  82        mNumJointNames = 0;
  83        mJointNames = NULL;
  84
  85        mTriangleIndices = NULL;
  86        mNumTriangleIndices = 0;
  87
  88        mReferenceData = NULL;
  89
  90        mLastIndexOffset = -1;
  91}
  92
  93//-----------------------------------------------------------------------------
  94// ~LLPolyMeshSharedData()
  95//-----------------------------------------------------------------------------
  96LLPolyMeshSharedData::~LLPolyMeshSharedData()
  97{
  98        freeMeshData();
  99        for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
 100        mMorphData.clear();
 101}
 102
 103//-----------------------------------------------------------------------------
 104// setupLOD()
 105//-----------------------------------------------------------------------------
 106void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
 107{
 108        mReferenceData = reference_data;
 109
 110        if (reference_data)
 111        {
 112                mBaseCoords = reference_data->mBaseCoords;
 113                mBaseNormals = reference_data->mBaseNormals;
 114                mBaseBinormals = reference_data->mBaseBinormals;
 115                mTexCoords = reference_data->mTexCoords;
 116                mDetailTexCoords = reference_data->mDetailTexCoords;
 117                mWeights = reference_data->mWeights;
 118                mHasWeights = reference_data->mHasWeights;
 119                mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
 120        }
 121}
 122
 123//-----------------------------------------------------------------------------
 124// LLPolyMeshSharedData::freeMeshData()
 125//-----------------------------------------------------------------------------
 126void LLPolyMeshSharedData::freeMeshData()
 127{
 128        if (!mReferenceData)
 129        {
 130                mNumVertices = 0;
 131
 132                delete [] mBaseCoords;
 133                mBaseCoords = NULL;
 134
 135                delete [] mBaseNormals;
 136                mBaseNormals = NULL;
 137
 138                delete [] mBaseBinormals;
 139                mBaseBinormals = NULL;
 140
 141                delete [] mTexCoords;
 142                mTexCoords = NULL;
 143
 144                delete [] mDetailTexCoords;
 145                mDetailTexCoords = NULL;
 146
 147                delete [] mWeights;
 148                mWeights = NULL;
 149        }
 150
 151        mNumFaces = 0;
 152        delete [] mFaces;
 153        mFaces = NULL;
 154
 155        mNumJointNames = 0;
 156        delete [] mJointNames;
 157        mJointNames = NULL;
 158
 159        delete [] mTriangleIndices;
 160        mTriangleIndices = NULL;
 161
 162//      mVertFaceMap.deleteAllData();
 163}
 164
 165// compate_int is used by the qsort function to sort the index array
 166int compare_int(const void *a, const void *b);
 167
 168//-----------------------------------------------------------------------------
 169// genIndices()
 170//-----------------------------------------------------------------------------
 171void LLPolyMeshSharedData::genIndices(S32 index_offset)
 172{
 173        if (index_offset == mLastIndexOffset)
 174        {
 175                return;
 176        }
 177
 178        delete []mTriangleIndices;
 179        mTriangleIndices = new U32[mNumTriangleIndices];
 180
 181        S32 cur_index = 0;
 182        for (S32 i = 0; i < mNumFaces; i++)
 183        {
 184                mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
 185                cur_index++;
 186                mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
 187                cur_index++;
 188                mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
 189                cur_index++;
 190        }
 191
 192        mLastIndexOffset = index_offset;
 193}
 194
 195//--------------------------------------------------------------------
 196// LLPolyMeshSharedData::getNumKB()
 197//--------------------------------------------------------------------
 198U32 LLPolyMeshSharedData::getNumKB()
 199{
 200        U32 num_kb = sizeof(LLPolyMesh);
 201
 202        if (!isLOD())
 203        {
 204                num_kb += mNumVertices *
 205                        ( sizeof(LLVector3) +   // coords
 206                          sizeof(LLVector3) +             // normals
 207                          sizeof(LLVector2) );    // texCoords
 208        }
 209
 210        if (mHasDetailTexCoords && !isLOD())
 211        {
 212                num_kb += mNumVertices * sizeof(LLVector2);     // detailTexCoords
 213        }
 214
 215        if (mHasWeights && !isLOD())
 216        {
 217                num_kb += mNumVertices * sizeof(float);         // weights
 218        }
 219
 220        num_kb += mNumFaces * sizeof(LLPolyFace);       // faces
 221
 222        num_kb /= 1024;
 223        return num_kb;
 224}
 225
 226//-----------------------------------------------------------------------------
 227// LLPolyMeshSharedData::allocateVertexData()
 228//-----------------------------------------------------------------------------
 229BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
 230{
 231        U32 i;
 232        mBaseCoords = new LLVector3[ numVertices ];
 233        mBaseNormals = new LLVector3[ numVertices ];
 234        mBaseBinormals = new LLVector3[ numVertices ];
 235        mTexCoords = new LLVector2[ numVertices ];
 236        mDetailTexCoords = new LLVector2[ numVertices ];
 237        mWeights = new F32[ numVertices ];
 238        for (i = 0; i < numVertices; i++)
 239        {
 240                mWeights[i] = 0.f;
 241        }
 242        mNumVertices = numVertices;
 243        return TRUE;
 244}
 245
 246//-----------------------------------------------------------------------------
 247// LLPolyMeshSharedData::allocateFaceData()
 248//-----------------------------------------------------------------------------
 249BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
 250{
 251        mFaces = new LLPolyFace[ numFaces ];
 252        mNumFaces = numFaces;
 253        mNumTriangleIndices = mNumFaces * 3;
 254        return TRUE;
 255}
 256
 257//-----------------------------------------------------------------------------
 258// LLPolyMeshSharedData::allocateJointNames()
 259//-----------------------------------------------------------------------------
 260BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
 261{
 262        mJointNames = new std::string[ numJointNames ];
 263        mNumJointNames = numJointNames;
 264        return TRUE;
 265}
 266
 267//--------------------------------------------------------------------
 268// LLPolyMeshSharedData::loadMesh()
 269//--------------------------------------------------------------------
 270BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
 271{
 272        //-------------------------------------------------------------------------
 273        // Open the file
 274        //-------------------------------------------------------------------------
 275        if(fileName.empty())
 276        {
 277                llerrs << "Filename is Empty!" << llendl;
 278                return FALSE;
 279        }
 280        LLFILE* fp = LLFile::fopen(fileName, "rb");                     /*Flawfinder: ignore*/
 281        if (!fp)
 282        {
 283                llerrs << "can't open: " << fileName << llendl;
 284                return FALSE;
 285        }
 286
 287        //-------------------------------------------------------------------------
 288        // Read a chunk
 289        //-------------------------------------------------------------------------
 290        char header[128];               /*Flawfinder: ignore*/
 291        if (fread(header, sizeof(char), 128, fp) != 128)
 292        {
 293                llwarns << "Short read" << llendl;
 294        }
 295
 296        //-------------------------------------------------------------------------
 297        // Check for proper binary header
 298        //-------------------------------------------------------------------------
 299        BOOL status = FALSE;
 300        if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 )       /*Flawfinder: ignore*/
 301        {
 302                lldebugs << "Loading " << fileName << llendl;
 303
 304                //----------------------------------------------------------------
 305                // File Header (seek past it)
 306                //----------------------------------------------------------------
 307                fseek(fp, 24, SEEK_SET);
 308
 309                //----------------------------------------------------------------
 310                // HasWeights
 311                //----------------------------------------------------------------
 312                U8 hasWeights;
 313                size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
 314                if (numRead != 1)
 315                {
 316                        llerrs << "can't read HasWeights flag from " << fileName << llendl;
 317                        return FALSE;
 318                }
 319                if (!isLOD())
 320                {
 321                        mHasWeights = (hasWeights==0) ? FALSE : TRUE;
 322                }
 323
 324                //----------------------------------------------------------------
 325                // HasDetailTexCoords
 326                //----------------------------------------------------------------
 327                U8 hasDetailTexCoords;
 328                numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
 329                if (numRead != 1)
 330                {
 331                        llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
 332                        return FALSE;
 333                }
 334
 335                //----------------------------------------------------------------
 336                // Position
 337                //----------------------------------------------------------------
 338                LLVector3 position;
 339                numRead = fread(position.mV, sizeof(float), 3, fp);
 340                llendianswizzle(position.mV, sizeof(float), 3);
 341                if (numRead != 3)
 342                {
 343                        llerrs << "can't read Position from " << fileName << llendl;
 344                        return FALSE;
 345                }
 346                setPosition( position );
 347
 348                //----------------------------------------------------------------
 349                // Rotation
 350                //----------------------------------------------------------------
 351                LLVector3 rotationAngles;
 352                numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
 353                llendianswizzle(rotationAngles.mV, sizeof(float), 3);
 354                if (numRead != 3)
 355                {
 356                        llerrs << "can't read RotationAngles from " << fileName << llendl;
 357                        return FALSE;
 358                }
 359
 360                U8 rotationOrder;
 361                numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
 362
 363                if (numRead != 1)
 364                {
 365                        llerrs << "can't read RotationOrder from " << fileName << llendl;
 366                        return FALSE;
 367                }
 368
 369                rotationOrder = 0;
 370
 371                setRotation( mayaQ(     rotationAngles.mV[0],
 372                                        rotationAngles.mV[1],
 373                                        rotationAngles.mV[2],
 374                                        (LLQuaternion::Order)rotationOrder ) );
 375
 376                //----------------------------------------------------------------
 377                // Scale
 378                //----------------------------------------------------------------
 379                LLVector3 scale;
 380                numRead = fread(scale.mV, sizeof(float), 3, fp);
 381                llendianswizzle(scale.mV, sizeof(float), 3);
 382                if (numRead != 3)
 383                {
 384                        llerrs << "can't read Scale from " << fileName << llendl;
 385                        return FALSE;
 386                }
 387                setScale( scale );
 388
 389                //-------------------------------------------------------------------------
 390                // Release any existing mesh geometry
 391                //-------------------------------------------------------------------------
 392                freeMeshData();
 393
 394                U16 numVertices = 0;
 395
 396                //----------------------------------------------------------------
 397                // NumVertices
 398                //----------------------------------------------------------------
 399                if (!isLOD())
 400                {
 401                        numRead = fread(&numVertices, sizeof(U16), 1, fp);
 402                        llendianswizzle(&numVertices, sizeof(U16), 1);
 403                        if (numRead != 1)
 404                        {
 405                                llerrs << "can't read NumVertices from " << fileName << llendl;
 406                                return FALSE;
 407                        }
 408
 409                        allocateVertexData( numVertices );      
 410
 411                        //----------------------------------------------------------------
 412                        // Coords
 413                        //----------------------------------------------------------------
 414                        numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
 415                        llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
 416                        if (numRead != numVertices)
 417                        {
 418                                llerrs << "can't read Coordinates from " << fileName << llendl;
 419                                return FALSE;
 420                        }
 421
 422                        //----------------------------------------------------------------
 423                        // Normals
 424                        //----------------------------------------------------------------
 425                        numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
 426                        llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
 427                        if (numRead != numVertices)
 428                        {
 429                                llerrs << " can't read Normals from " << fileName << llendl;
 430                                return FALSE;
 431                        }
 432
 433                        //----------------------------------------------------------------
 434                        // Binormals
 435                        //----------------------------------------------------------------
 436                        numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
 437                        llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
 438                        if (numRead != numVertices)
 439                        {
 440                                llerrs << " can't read Binormals from " << fileName << llendl;
 441                                return FALSE;
 442                        }
 443
 444
 445                        //----------------------------------------------------------------
 446                        // TexCoords
 447                        //----------------------------------------------------------------
 448                        numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
 449                        llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
 450                        if (numRead != numVertices)
 451                        {
 452                                llerrs << "can't read TexCoords from " << fileName << llendl;
 453                                return FALSE;
 454                        }
 455
 456                        //----------------------------------------------------------------
 457                        // DetailTexCoords
 458                        //----------------------------------------------------------------
 459                        if (mHasDetailTexCoords)
 460                        {
 461                                numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
 462                                llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
 463                                if (numRead != numVertices)
 464                                {
 465                                        llerrs << "can't read DetailTexCoords from " << fileName << llendl;
 466                                        return FALSE;
 467                                }
 468                        }
 469
 470                        //----------------------------------------------------------------
 471                        // Weights
 472                        //----------------------------------------------------------------
 473                        if (mHasWeights)
 474                        {
 475                                numRead = fread(mWeights, sizeof(float), numVertices, fp);
 476                                llendianswizzle(mWeights, sizeof(float), numVertices);
 477                                if (numRead != numVertices)
 478                                {
 479                                        llerrs << "can't read Weights from " << fileName << llendl;
 480                                        return FALSE;
 481                                }
 482                        }
 483                }
 484
 485                //----------------------------------------------------------------
 486                // NumFaces
 487                //----------------------------------------------------------------
 488                U16 numFaces;
 489                numRead = fread(&numFaces, sizeof(U16), 1, fp);
 490                llendianswizzle(&numFaces, sizeof(U16), 1);
 491                if (numRead != 1)
 492                {
 493                        llerrs << "can't read NumFaces from " << fileName << llendl;
 494                        return FALSE;
 495                }
 496                allocateFaceData( numFaces );
 497
 498
 499                //----------------------------------------------------------------
 500                // Faces
 501                //----------------------------------------------------------------
 502                U32 i;
 503                U32 numTris = 0;
 504                for (i = 0; i < numFaces; i++)
 505                {
 506                        S16 face[3];
 507                        numRead = fread(face, sizeof(U16), 3, fp);
 508                        llendianswizzle(face, sizeof(U16), 3);
 509                        if (numRead != 3)
 510                        {
 511                                llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
 512                                return FALSE;
 513                        }
 514                        if (mReferenceData)
 515                        {
 516                                llassert(face[0] < mReferenceData->mNumVertices);
 517                                llassert(face[1] < mReferenceData->mNumVertices);
 518                                llassert(face[2] < mReferenceData->mNumVertices);
 519                        }
 520                        
 521                        if (isLOD())
 522                        {
 523                                // store largest index in case of LODs
 524                                for (S32 j = 0; j < 3; j++)
 525                                {
 526                                        if (face[j] > mNumVertices - 1)
 527                                        {
 528                                                mNumVertices = face[j] + 1;
 529                                        }
 530                                }
 531                        }
 532                        mFaces[i][0] = face[0];
 533                        mFaces[i][1] = face[1];
 534                        mFaces[i][2] = face[2];
 535
 536//                      S32 j;
 537//                      for(j = 0; j < 3; j++)
 538//                      {
 539//                              LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
 540//                              if (!face_list)
 541//                              {
 542//                                      face_list = new LLDynamicArray<S32>;
 543//                                      mVertFaceMap.addData(face[j], face_list);
 544//                              }
 545//                              face_list->put(i);
 546//                      }
 547
 548                        numTris++;
 549                }
 550
 551                lldebugs << "verts: " << numVertices 
 552                         << ", faces: "   << numFaces
 553                         << ", tris: "    << numTris
 554                         << llendl;
 555
 556                //----------------------------------------------------------------
 557                // NumSkinJoints
 558                //----------------------------------------------------------------
 559                if (!isLOD())
 560                {
 561                        U16 numSkinJoints = 0;
 562                        if ( mHasWeights )
 563                        {
 564                                numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
 565                                llendianswizzle(&numSkinJoints, sizeof(U16), 1);
 566                                if (numRead != 1)
 567                                {
 568                                        llerrs << "can't read NumSkinJoints from " << fileName << llendl;
 569                                        return FALSE;
 570                                }
 571                                allocateJointNames( numSkinJoints );
 572                        }
 573
 574                        //----------------------------------------------------------------
 575                        // SkinJoints
 576                        //----------------------------------------------------------------
 577                        for (i=0; i < numSkinJoints; i++)
 578                        {
 579                                char jointName[64+1];
 580                                numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
 581                                jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
 582                                if (numRead != 1)
 583                                {
 584                                        llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
 585                                        return FALSE;
 586                                }
 587
 588                                std::string *jn = &mJointNames[i];
 589                                *jn = jointName;
 590                        }
 591
 592                        //-------------------------------------------------------------------------
 593                        // look for morph section
 594                        //-------------------------------------------------------------------------
 595                        char morphName[64+1];
 596                        morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
 597                        while(fread(&morphName, sizeof(char), 64, fp) == 64)
 598                        {
 599                                if (!strcmp(morphName, "End Morphs"))
 600                                {
 601                                        // we reached the end of the morphs
 602                                        break;
 603                                }
 604                                LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
 605
 606                                BOOL result = morph_data->loadBinary(fp, this);
 607
 608                                if (!result)
 609                                {
 610                                        delete morph_data;
 611                                        continue;
 612                                }
 613
 614                                mMorphData.insert(morph_data);
 615
 616                                if (!strcmp(morphName, "Breast_Female_Cleavage"))
 617                                {
 618                                        mMorphData.insert(clone_morph_param_cleavage(morph_data,
 619                                                                                     .75f,
 620                                                                                     "Breast_Physics_LeftRight_Driven"));
 621                                }
 622
 623                                if (!strcmp(morphName, "Breast_Female_Cleavage"))
 624                                {
 625                                        mMorphData.insert(clone_morph_param_duplicate(morph_data,
 626										      "Breast_Physics_InOut_Driven"));
 627                                }
 628                                if (!strcmp(morphName, "Breast_Gravity"))
 629                                {
 630                                        mMorphData.insert(clone_morph_param_duplicate(morph_data,
 631										      "Breast_Physics_UpDown_Driven"));
 632                                }
 633
 634                                if (!strcmp(morphName, "Big_Belly_Torso"))
 635                                {
 636                                        mMorphData.insert(clone_morph_param_direction(morph_data,
 637										      LLVector3(0,0,0.05f),
 638										      "Belly_Physics_Torso_UpDown_Driven"));
 639                                }
 640
 641                                if (!strcmp(morphName, "Big_Belly_Legs"))
 642                                {
 643                                        mMorphData.insert(clone_morph_param_direction(morph_data,
 644										      LLVector3(0,0,0.05f),
 645										      "Belly_Physics_Legs_UpDown_Driven"));
 646                                }
 647
 648                                if (!strcmp(morphName, "skirt_belly"))
 649                                {
 650                                        mMorphData.insert(clone_morph_param_direction(morph_data,
 651										      LLVector3(0,0,0.05f),
 652										      "Belly_Physics_Skirt_UpDown_Driven"));
 653                                }
 654
 655                                if (!strcmp(morphName, "Small_Butt"))
 656                                {
 657                                        mMorphData.insert(clone_morph_param_direction(morph_data,
 658										      LLVector3(0,0,0.05f),
 659										      "Butt_Physics_UpDown_Driven"));
 660                                }
 661                                if (!strcmp(morphName, "Small_Butt"))
 662                                {
 663                                        mMorphData.insert(clone_morph_param_direction(morph_data,
 664										      LLVector3(0,0.03f,0),
 665										      "Butt_Physics_LeftRight_Driven"));
 666                                }
 667                        }
 668
 669                        S32 numRemaps;
 670                        if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
 671                        {
 672                                llendianswizzle(&numRemaps, sizeof(S32), 1);
 673                                for (S32 i = 0; i < numRemaps; i++)
 674                                {
 675                                        S32 remapSrc;
 676                                        S32 remapDst;
 677                                        if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
 678                                        {
 679                                                llerrs << "can't read source vertex in vertex remap data" << llendl;
 680                                                break;
 681                                        }
 682                                        if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
 683                                        {
 684                                                llerrs << "can't read destination vertex in vertex remap data" << llendl;
 685                                                break;
 686                                        }
 687                                        llendianswizzle(&remapSrc, sizeof(S32), 1);
 688                                        llendianswizzle(&remapDst, sizeof(S32), 1);
 689
 690                                        mSharedVerts[remapSrc] = remapDst;
 691                                }
 692                        }
 693                }
 694
 695                status = TRUE;
 696        }
 697        else
 698        {
 699                llerrs << "invalid mesh file header: " << fileName << llendl;
 700                status = FALSE;
 701        }
 702
 703        if (0 == mNumJointNames)
 704        {
 705                allocateJointNames(1);
 706        }
 707
 708        fclose( fp );
 709
 710        return status;
 711}
 712
 713//-----------------------------------------------------------------------------
 714// getSharedVert()
 715//-----------------------------------------------------------------------------
 716const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
 717{
 718        if (mSharedVerts.count(vert) > 0)
 719        {
 720                return &mSharedVerts[vert];
 721        }
 722        return NULL;
 723}
 724
 725//-----------------------------------------------------------------------------
 726// getUV()
 727//-----------------------------------------------------------------------------
 728const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
 729{
 730        // TODO: convert all index variables to S32
 731        llassert((S32)index < mNumVertices);
 732
 733        return mTexCoords[index];
 734}
 735
 736//-----------------------------------------------------------------------------
 737// LLPolyMesh()
 738//-----------------------------------------------------------------------------
 739LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
 740{       
 741	LLMemType mt(LLMemType::MTYPE_AVATAR_MESH);
 742
 743	llassert(shared_data);
 744
 745	mSharedData = shared_data;
 746	mReferenceMesh = reference_mesh;
 747	mAvatarp = NULL;
 748	mVertexData = NULL;
 749
 750	mCurVertexCount = 0;
 751	mFaceIndexCount = 0;
 752	mFaceIndexOffset = 0;
 753	mFaceVertexCount = 0;
 754	mFaceVertexOffset = 0;
 755
 756	if (shared_data->isLOD() && reference_mesh)
 757	{
 758		mCoords = reference_mesh->mCoords;
 759		mNormals = reference_mesh->mNormals;
 760		mScaledNormals = reference_mesh->mScaledNormals;
 761		mBinormals = reference_mesh->mBinormals;
 762		mScaledBinormals = reference_mesh->mScaledBinormals;
 763		mTexCoords = reference_mesh->mTexCoords;
 764		mClothingWeights = reference_mesh->mClothingWeights;
 765	}
 766	else
 767	{
 768		// Allocate memory without initializing every vector
 769		// NOTE: This makes asusmptions about the size of LLVector[234]
 770		int nverts = mSharedData->mNumVertices;
 771		int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
 772		//use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
 773		mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
 774		int offset = 0;
 775		mCoords				= 	(LLVector4*)(mVertexData + offset); offset += 4*nverts;
 776		mNormals			=	(LLVector4*)(mVertexData + offset); offset += 4*nverts;
 777		mClothingWeights	= 	(LLVector4*)(mVertexData + offset); offset += 4*nverts;
 778		mTexCoords			= 	(LLVector2*)(mVertexData + offset); offset += 2*nverts;
 779
 780		// these members don't need to be 16-byte aligned, but the first one might be
 781		// read during an aligned memcpy of mTexCoords
 782		mScaledNormals =                (LLVector3*)(mVertexData + offset); offset += 3*nverts;
 783		mBinormals =                    (LLVector3*)(mVertexData + offset); offset += 3*nverts;
 784		mScaledBinormals =              (LLVector3*)(mVertexData + offset); offset += 3*nverts; 
 785		initializeForMorph();
 786	}
 787}
 788
 789
 790//-----------------------------------------------------------------------------
 791// ~LLPolyMesh()
 792//-----------------------------------------------------------------------------
 793LLPolyMesh::~LLPolyMesh()
 794{
 795        S32 i;
 796        for (i = 0; i < mJointRenderData.count(); i++)
 797        {
 798                delete mJointRenderData[i];
 799                mJointRenderData[i] = NULL;
 800        }
 801
 802		ll_aligned_free_16(mVertexData);
 803
 804}
 805
 806
 807//-----------------------------------------------------------------------------
 808// LLPolyMesh::getMesh()
 809//-----------------------------------------------------------------------------
 810LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_mesh)
 811{
 812        //-------------------------------------------------------------------------
 813        // search for an existing mesh by this name
 814        //-------------------------------------------------------------------------
 815        LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
 816        if (meshSharedData)
 817        {
 818//              llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
 819                LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
 820                return poly_mesh;
 821        }
 822
 823        //-------------------------------------------------------------------------
 824        // if not found, create a new one, add it to the list
 825        //-------------------------------------------------------------------------
 826        std::string full_path;
 827        full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
 828
 829        LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
 830        if (reference_mesh)
 831        {
 832                mesh_data->setupLOD(reference_mesh->getSharedData());
 833        }
 834        if ( ! mesh_data->loadMesh( full_path ) )
 835        {
 836                delete mesh_data;
 837                return NULL;
 838        }
 839
 840        LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
 841
 842//      llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
 843        sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
 844
 845        return poly_mesh;
 846}
 847
 848//-----------------------------------------------------------------------------
 849// LLPolyMesh::freeAllMeshes()
 850//-----------------------------------------------------------------------------
 851void LLPolyMesh::freeAllMeshes()
 852{
 853        // delete each item in the global lists
 854        for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
 855        sGlobalSharedMeshList.clear();
 856}
 857
 858LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
 859{
 860        return mSharedData;
 861}
 862
 863
 864//--------------------------------------------------------------------
 865// LLPolyMesh::dumpDiagInfo()
 866//--------------------------------------------------------------------
 867void LLPolyMesh::dumpDiagInfo()
 868{
 869        // keep track of totals
 870        U32 total_verts = 0;
 871        U32 total_faces = 0;
 872        U32 total_kb = 0;
 873
 874        std::string buf;
 875
 876        llinfos << "-----------------------------------------------------" << llendl;
 877        llinfos << "       Global PolyMesh Table (DEBUG only)" << llendl;
 878        llinfos << "   Verts    Faces  Mem(KB) Name" << llendl;
 879        llinfos << "-----------------------------------------------------" << llendl;
 880
 881        // print each loaded mesh, and it's memory usage
 882        for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
 883            iter != sGlobalSharedMeshList.end(); ++iter)
 884        {
 885                const std::string& mesh_name = iter->first;
 886                LLPolyMeshSharedData* mesh = iter->second;
 887
 888                S32 num_verts = mesh->mNumVertices;
 889                S32 num_faces = mesh->mNumFaces;
 890                U32 num_kb = mesh->getNumKB();
 891
 892                buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
 893                llinfos << buf << llendl;
 894
 895                total_verts += num_verts;
 896                total_faces += num_faces;
 897                total_kb += num_kb;
 898        }
 899
 900        llinfos << "-----------------------------------------------------" << llendl;
 901        buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
 902        llinfos << buf << llendl;
 903        llinfos << "-----------------------------------------------------" << llendl;
 904}
 905
 906//-----------------------------------------------------------------------------
 907// getWritableCoords()
 908//-----------------------------------------------------------------------------
 909LLVector4 *LLPolyMesh::getWritableCoords()
 910{
 911        return mCoords;
 912}
 913
 914//-----------------------------------------------------------------------------
 915// getWritableNormals()
 916//-----------------------------------------------------------------------------
 917LLVector4 *LLPolyMesh::getWritableNormals()
 918{
 919        return mNormals;
 920}
 921
 922//-----------------------------------------------------------------------------
 923// getWritableBinormals()
 924//-----------------------------------------------------------------------------
 925LLVector3 *LLPolyMesh::getWritableBinormals()
 926{
 927        return mBinormals;
 928}
 929
 930
 931//-----------------------------------------------------------------------------
 932// getWritableClothingWeights()
 933//-----------------------------------------------------------------------------
 934LLVector4       *LLPolyMesh::getWritableClothingWeights()
 935{
 936        return mClothingWeights;
 937}
 938
 939//-----------------------------------------------------------------------------
 940// getWritableTexCoords()
 941//-----------------------------------------------------------------------------
 942LLVector2       *LLPolyMesh::getWritableTexCoords()
 943{
 944        return mTexCoords;
 945}
 946
 947//-----------------------------------------------------------------------------
 948// getScaledNormals()
 949//-----------------------------------------------------------------------------
 950LLVector3 *LLPolyMesh::getScaledNormals()
 951{
 952        return mScaledNormals;
 953}
 954
 955//-----------------------------------------------------------------------------
 956// getScaledBinormals()
 957//-----------------------------------------------------------------------------
 958LLVector3 *LLPolyMesh::getScaledBinormals()
 959{
 960        return mScaledBinormals;
 961}
 962
 963
 964//-----------------------------------------------------------------------------
 965// initializeForMorph()
 966//-----------------------------------------------------------------------------
 967void LLPolyMesh::initializeForMorph()
 968{
 969    for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
 970	{
 971		mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
 972		mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
 973	}
 974
 975	memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices);	/*Flawfinder: ignore*/
 976	memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices);	/*Flawfinder: ignore*/
 977	memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices);		/*Flawfinder: ignore*/
 978	memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices);		/*Flawfinder: ignore*/
 979	memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
 980}
 981
 982//-----------------------------------------------------------------------------
 983// getMorphData()
 984//-----------------------------------------------------------------------------
 985LLPolyMorphData*        LLPolyMesh::getMorphData(const std::string& morph_name)
 986{
 987        if (!mSharedData)
 988                return NULL;
 989        for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
 990             iter != mSharedData->mMorphData.end(); ++iter)
 991        {
 992                LLPolyMorphData *morph_data = *iter;
 993                if (morph_data->getName() == morph_name)
 994                {
 995                        return morph_data;
 996                }
 997        }
 998        return NULL;
 999}
1000
1001//-----------------------------------------------------------------------------
1002// removeMorphData()
1003//-----------------------------------------------------------------------------
1004// // erasing but not deleting seems bad, but fortunately we don't actually use this...
1005// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
1006// {
1007//      if (!mSharedData)
1008//              return;
1009//      mSharedData->mMorphData.erase(morph_target);
1010// }
1011
1012//-----------------------------------------------------------------------------
1013// deleteAllMorphData()
1014//-----------------------------------------------------------------------------
1015// void LLPolyMesh::deleteAllMorphData()
1016// {
1017//      if (!mSharedData)
1018//              return;
1019
1020//      for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
1021//      mSharedData->mMorphData.clear();
1022// }
1023
1024//-----------------------------------------------------------------------------
1025// getWritableWeights()
1026//-----------------------------------------------------------------------------
1027F32*    LLPolyMesh::getWritableWeights() const
1028{
1029        return mSharedData->mWeights;
1030}
1031
1032//-----------------------------------------------------------------------------
1033// LLPolySkeletalDistortionInfo()
1034//-----------------------------------------------------------------------------
1035LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
1036{
1037}
1038
1039BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
1040{
1041        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
1042        
1043        if (!LLViewerVisualParamInfo::parseXml(node))
1044                return FALSE;
1045
1046        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
1047
1048        if (NULL == skeletalParam)
1049        {
1050                llwarns << "Failed to getChildByName(\"param_skeleton\")"
1051                        << llendl;
1052                return FALSE;
1053        }
1054
1055        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
1056        {
1057                if (bone->hasName("bone"))
1058                {
1059                        std::string name;
1060                        LLVector3 scale;
1061                        LLVector3 pos;
1062                        BOOL haspos = FALSE;
1063                        
1064                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
1065                        if (!bone->getFastAttributeString(name_string, name))
1066                        {
1067                                llwarns << "No bone name specified for skeletal param." << llendl;
1068                                continue;
1069                        }
1070
1071                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
1072                        if (!bone->getFastAttributeVector3(scale_string, scale))
1073                        {
1074                                llwarns << "No scale specified for bone " << name << "." << llendl;
1075                                continue;
1076                        }
1077
1078                        // optional offset deformation (translation)
1079                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
1080                        if (bone->getFastAttributeVector3(offset_string, pos))
1081                        {
1082                                haspos = TRUE;
1083                        }
1084                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
1085                }
1086                else
1087                {
1088                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
1089                        continue;
1090                }
1091        }
1092        return TRUE;
1093}
1094
1095//-----------------------------------------------------------------------------
1096// LLPolySkeletalDistortion()
1097//-----------------------------------------------------------------------------
1098LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
1099{
1100        mAvatar = avatarp;
1101        mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
1102}
1103
1104//-----------------------------------------------------------------------------
1105// ~LLPolySkeletalDistortion()
1106//-----------------------------------------------------------------------------
1107LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
1108{
1109}
1110
1111BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
1112{
1113        llassert(mInfo == NULL);
1114        if (info->mID < 0)
1115                return FALSE;
1116        mInfo = info;
1117        mID = info->mID;
1118        setWeight(getDefaultWeight(), FALSE );
1119
1120        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
1121        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
1122        {
1123                LLPolySkeletalBoneInfo *bone_info = &(*iter);
1124                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
1125                if (!joint)
1126                {
1127                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
1128                        continue;
1129                }
1130
1131                if (mJointScales.find(joint) != mJointScales.end())
1132                {
1133                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
1134                }
1135
1136                // store it
1137                mJointScales[joint] = bone_info->mScaleDeformation;
1138
1139                // apply to children that need to inherit it
1140                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
1141                     iter != joint->mChildren.end(); ++iter)
1142                {
1143                        LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
1144                        if (child_joint->inheritScale())
1145                        {
1146                                LLVector3 childDeformation = LLVector3(child_joint->getScale());
1147                                childDeformation.scaleVec(bone_info->mScaleDeformation);
1148                                mJointScales[child_joint] = childDeformation;
1149                        }
1150                }
1151
1152                if (bone_info->mHasPositionDeformation)
1153                {
1154                        if (mJointOffsets.find(joint) != mJointOffsets.end())
1155                        {
1156                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
1157                        }
1158                        mJointOffsets[joint] = bone_info->mPositionDeformation;
1159                }
1160        }
1161        return TRUE;
1162}
1163
1164/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
1165{
1166        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
1167        *new_param = *this;
1168        return new_param;
1169}
1170
1171//-----------------------------------------------------------------------------
1172// apply()
1173//-----------------------------------------------------------------------------
1174void LLPolySkeletalDistortion::apply( ESex avatar_sex )
1175{
1176        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
1177
1178        LLJoint* joint;
1179        joint_vec_map_t::iterator iter;
1180
1181        for (iter = mJointScales.begin();
1182             iter != mJointScales.end();
1183             iter++)
1184        {
1185                joint = iter->first;
1186                LLVector3 newScale = joint->getScale();
1187                LLVector3 scaleDelta = iter->second;
1188                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
1189                joint->setScale(newScale);
1190        }
1191
1192        for (iter = mJointOffsets.begin();
1193             iter != mJointOffsets.end();
1194             iter++)
1195        {
1196                joint = iter->first;
1197                LLVector3 newPosition = joint->getPosition();
1198                LLVector3 positionDelta = iter->second;
1199                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
1200                joint->setPosition(newPosition);
1201        }
1202
1203        if (mLastWeight != mCurWeight && !mIsAnimating)
1204        {
1205                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
1206        }
1207        mLastWeight = mCurWeight;
1208}
1209
1210
1211LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
1212					     const std::string &name)
1213{
1214        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
1215        cloned_morph_data->mName = name;
1216        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
1217        {
1218                cloned_morph_data->mCoords[v] = src_data->mCoords[v];
1219                cloned_morph_data->mNormals[v] = src_data->mNormals[v];
1220                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
1221        }
1222        return cloned_morph_data;
1223}
1224
1225LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
1226					     const LLVector3 &direction,
1227					     const std::string &name)
1228{
1229        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
1230        cloned_morph_data->mName = name;
1231        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
1232        {
1233                cloned_morph_data->mCoords[v] = direction;
1234                cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
1235                cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
1236        }
1237        return cloned_morph_data;
1238}
1239
1240LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
1241                                            F32 scale,
1242                                            const std::string &name)
1243{
1244        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
1245        cloned_morph_data->mName = name;
1246        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
1247        {
1248                cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale;
1249                cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale;
1250                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale;
1251                if (cloned_morph_data->mCoords[v][1] < 0)
1252                {
1253                        cloned_morph_data->mCoords[v][1] *= -1;
1254                        cloned_morph_data->mNormals[v][1] *= -1;
1255                        cloned_morph_data->mBinormals[v][1] *= -1;
1256                }
1257        }
1258        return cloned_morph_data;
1259}
1260
1261// End