diff options
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llprimitive/lldaeloader.cpp | 144 | ||||
-rw-r--r-- | indra/llprimitive/lldaeloader.h | 2 | ||||
-rw-r--r-- | indra/llprimitive/llmodel.cpp | 32 | ||||
-rw-r--r-- | indra/llprimitive/llmodelloader.cpp | 38 | ||||
-rw-r--r-- | indra/llprimitive/llmodelloader.h | 18 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.cpp | 14 | ||||
-rw-r--r-- | indra/llprimitive/llprimitive.h | 19 | ||||
-rw-r--r-- | indra/llprimitive/lltextureanim.cpp | 24 |
9 files changed, 178 insertions, 115 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index dd2e806dda..7b6d04b096 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -80,7 +80,7 @@ target_link_libraries(llprimitive ${LLXML_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLCHARACTER_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ) diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 8f75d89e5a..dfa29fb539 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -343,7 +343,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa return LLModel::NO_ERRORS ; } -LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolylistRef& poly) +LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolylistRef& poly, LLSD& log_msg) { domPRef p = poly->getP(); domListOfUInts& idx = p->getValue(); @@ -403,6 +403,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac LLVolumeFace::VertexMapData::PointMap point_map; U32 cur_idx = 0; + bool log_tc_msg = true; for (U32 i = 0; i < vcount.getCount(); ++i) { //for each polygon U32 first_index = 0; @@ -426,8 +427,21 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac if (tc_source) { - cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0], - tc[idx[cur_idx+tc_offset]*2+1]); + U64 idx_x = idx[cur_idx + tc_offset] * 2 + 0; + U64 idx_y = idx[cur_idx + tc_offset] * 2 + 1; + + if (idx_y < tc.getCount()) + { + cv.mTexCoord.setVec(tc[idx_x], tc[idx_y]); + } + else if (log_tc_msg) + { + log_tc_msg = false; + LL_WARNS() << "Texture coordinates data is not complete." << LL_ENDL; + LLSD args; + args["Message"] = "IncompleteTC"; + log_msg.append(args); + } } if (norm_source) @@ -1215,7 +1229,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do for (S32 i = 0; i < childCount; ++i) { domNode* pNode = daeSafeCast<domNode>(children[i]); - if ( isNodeAJoint( pNode ) ) + if (pNode) { processJointNode( pNode, mJointList ); } @@ -1458,7 +1472,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do std::string lookingForJoint = (*jointIt).c_str(); //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key //and store it in the alternate bind matrix - if ( mJointMap.find( lookingForJoint ) != mJointMap.end() ) + if (mJointMap.find(lookingForJoint) != mJointMap.end() + && model->mSkinInfo.mInvBindMatrix.size() > i) { LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); @@ -1470,6 +1485,12 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } + U32 bind_count = model->mSkinInfo.mAlternateBindMatrix.size(); + if (bind_count > 0 && bind_count != jointCnt) + { + LL_WARNS("Mesh") << "Model " << model->mLabel << " has invalid joint bind matrix list." << LL_ENDL; + } + //grab raw position array domVertices* verts = mesh->getVertices(); @@ -1784,7 +1805,7 @@ void LLDAELoader::extractTranslationViaElement( daeElement* pTranslateElement, L { if ( pTranslateElement ) { - domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement ); + domTranslate* pTranslateChild = static_cast<domTranslate*>( pTranslateElement ); domFloat3 translateChild = pTranslateChild->getValue(); LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); transform.setTranslation( singleJointTranslation ); @@ -1834,59 +1855,61 @@ void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTran //LL_WARNS()<<"ProcessJointNode# Node:" <<pNode->getName()<<LL_ENDL; //1. handle the incoming node - extract out translation via SID or element + if (isNodeAJoint(pNode)) + { + LLMatrix4 workingTransform; - LLMatrix4 workingTransform; - - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolverA( pNode, "./translate" ); - domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() ); - daeSIDResolver jointResolverB( pNode, "./location" ); - domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() ); + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolverA(pNode, "./translate"); + domTranslate* pTranslateA = daeSafeCast<domTranslate>(jointResolverA.getElement()); + daeSIDResolver jointResolverB(pNode, "./location"); + domTranslate* pTranslateB = daeSafeCast<domTranslate>(jointResolverB.getElement()); - //Translation via SID was successful - if ( pTranslateA ) - { - extractTranslation( pTranslateA, workingTransform ); - } - else - if ( pTranslateB ) - { - extractTranslation( pTranslateB, workingTransform ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pNode, "translate" ); - if ( !pTranslateElement || pTranslateElement->typeID() != domTranslate::ID() ) - { - //LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; - daeSIDResolver jointResolver( pNode, "./matrix" ); - domMatrix* pMatrix = daeSafeCast<domMatrix>( jointResolver.getElement() ); - if ( pMatrix ) - { - //LL_INFOS()<<"A matrix SID was however found!"<<LL_ENDL; - domFloat4x4 domArray = pMatrix->getValue(); - for ( int i = 0; i < 4; i++ ) - { - for( int j = 0; j < 4; j++ ) - { - workingTransform.mMatrix[i][j] = domArray[i + j*4]; - } - } - } - else - { - LL_WARNS()<< "The found element is not translate or matrix node - most likely a corrupt export!" <<LL_ENDL; - } - } - else - { - extractTranslationViaElement( pTranslateElement, workingTransform ); - } - } + //Translation via SID was successful + if (pTranslateA) + { + extractTranslation(pTranslateA, workingTransform); + } + else + if (pTranslateB) + { + extractTranslation(pTranslateB, workingTransform); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement(pNode, "translate"); + if (!pTranslateElement || pTranslateElement->typeID() != domTranslate::ID()) + { + //LL_WARNS()<< "The found element is not a translate node" <<LL_ENDL; + daeSIDResolver jointResolver(pNode, "./matrix"); + domMatrix* pMatrix = daeSafeCast<domMatrix>(jointResolver.getElement()); + if (pMatrix) + { + //LL_INFOS()<<"A matrix SID was however found!"<<LL_ENDL; + domFloat4x4 domArray = pMatrix->getValue(); + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + workingTransform.mMatrix[i][j] = domArray[i + j * 4]; + } + } + } + else + { + LL_WARNS() << "The found element is not translate or matrix node - most likely a corrupt export!" << LL_ENDL; + } + } + else + { + extractTranslationViaElement(pTranslateElement, workingTransform); + } + } - //Store the working transform relative to the nodes name. - jointTransforms[ pNode->getName() ] = workingTransform; + //Store the working transform relative to the nodes name. + jointTransforms[pNode->getName()] = workingTransform; + } //2. handle the nodes children @@ -2356,7 +2379,7 @@ LLColor4 LLDAELoader::getDaeColor(daeElement* element) return value; } -bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh) +bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& log_msg) { LLModel::EModelStatus status = LLModel::NO_ERRORS; domTriangles_Array& tris = mesh->getTriangles_array(); @@ -2378,7 +2401,7 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh) for (U32 i = 0; i < polys.getCount(); ++i) { domPolylistRef& poly = polys.get(i); - status = load_face_from_dom_polylist(pModel->getVolumeFaces(), pModel->getMaterialList(), poly); + status = load_face_from_dom_polylist(pModel->getVolumeFaces(), pModel->getMaterialList(), poly, log_msg); if(status != LLModel::NO_ERRORS) { @@ -2442,7 +2465,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo // Get the whole set of volume faces // - addVolumeFacesFromDomMesh(ret, mesh); + addVolumeFacesFromDomMesh(ret, mesh, mWarningsArray); U32 volume_faces = ret->getNumVolumeFaces(); @@ -2515,7 +2538,8 @@ bool LLDAELoader::createVolumeFacesFromDomMesh(LLModel* pModel, domMesh* mesh) { pModel->ClearFacesAndMaterials(); - addVolumeFacesFromDomMesh(pModel, mesh); + LLSD placeholder; + addVolumeFacesFromDomMesh(pModel, mesh, placeholder); if (pModel->getNumVolumeFaces() > 0) { diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 4e990dbe5e..2b211343e1 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -89,7 +89,7 @@ protected: //Verify that a controller matches vertex counts bool verifyController( domController* pController ); - static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh); + static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg); static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh); static LLModel* loadModelFromDomMesh(domMesh* mesh); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 37548e3fe3..702a1b5238 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -434,7 +434,7 @@ void LLModel::generateNormals(F32 angle_cutoff) if (vol_face.mNumIndices > 65535) { - LL_WARNS() << "Too many vertices for normal generation to work." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL; continue; } @@ -1100,7 +1100,7 @@ bool LLModel::loadModel(std::istream& is) { if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) { - LL_WARNS() << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; return false; } } @@ -1132,7 +1132,7 @@ bool LLModel::loadModel(std::istream& is) if (header[lod_name[lod]]["offset"].asInteger() == -1 || header[lod_name[lod]]["size"].asInteger() == 0 ) { //cannot load requested LOD - LL_WARNS() << "LoD data is invalid!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL; return false; } @@ -1195,7 +1195,7 @@ bool LLModel::loadModel(std::istream& is) } else { - LL_WARNS() << "unpackVolumeFaces failed!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL; } return false; @@ -1223,7 +1223,7 @@ bool LLModel::isMaterialListSubset( LLModel* ref ) if (!foundRef) { - LL_INFOS() << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; + LL_INFOS("MESHSKININFO") << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; return false; } } @@ -1259,7 +1259,7 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn bool isASubset = isMaterialListSubset( ref ); if ( !isASubset ) { - LL_INFOS()<<"Material of model is not a subset of reference."<<LL_ENDL; + LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL; return false; } @@ -1398,6 +1398,14 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) mInvBindMatrix.push_back(mat); } + + if (mJointNames.size() != mInvBindMatrix.size()) + { + LL_WARNS("MESHSKININFO") << "Joints vs bind matrix count mismatch. Dropping joint bindings." << LL_ENDL; + mJointNames.clear(); + mJointNums.clear(); + mInvBindMatrix.clear(); + } } if (skin.has("bind_shape_matrix")) @@ -1579,7 +1587,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) range = max-min; - U16 count = position.size()/6; + U16 count = (U16)(position.size()/6); for (U32 j = 0; j < count; ++j) { @@ -1842,14 +1850,14 @@ bool validate_face(const LLVolumeFace& face) { if (face.mIndices[i] >= face.mNumVertices) { - LL_WARNS() << "Face has invalid index." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL; return false; } } if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) { - LL_WARNS() << "Face has invalid number of indices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL; return false; } @@ -1879,7 +1887,7 @@ bool validate_model(const LLModel* mdl) { if (mdl->getNumVolumeFaces() == 0) { - LL_WARNS() << "Model has no faces!" << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL; return false; } @@ -1887,13 +1895,13 @@ bool validate_model(const LLModel* mdl) { if (mdl->getVolumeFace(i).mNumVertices == 0) { - LL_WARNS() << "Face has no vertices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL; return false; } if (mdl->getVolumeFace(i).mNumIndices == 0) { - LL_WARNS() << "Face has no indices." << LL_ENDL; + LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL; return false; } diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 4e468ff45f..5171621007 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -127,7 +127,7 @@ LLModelLoader::LLModelLoader( , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) , mRigValidJointUpload(true) -, mLegacyRigValid(true) +, mLegacyRigFlags(0) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) @@ -136,6 +136,7 @@ LLModelLoader::LLModelLoader( { assert_main_thread(); sActiveLoaderList.push_back(this) ; + mWarningsArray = LLSD::emptyArray(); } LLModelLoader::~LLModelLoader() @@ -146,6 +147,7 @@ LLModelLoader::~LLModelLoader() void LLModelLoader::run() { + mWarningsArray.clear(); doLoadModel(); doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } @@ -387,7 +389,7 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st //2. It is suitable for upload as standard av with just skin weights bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); - bool isRigLegacyOK = isRigLegacy( jointListFromAsset ); + U32 legacy_rig_flags = determineRigLegacyFlags( jointListFromAsset ); // It's OK that both could end up being true. @@ -401,19 +403,16 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st setRigValidForJointPositionUpload( false ); } - if ( !isRigLegacyOK) - { - // This starts out true, becomes false if false for any loaded - // mesh. - setLegacyRigValid( false ); - } + legacy_rig_flags |= getLegacyRigFlags(); + // This starts as 0, changes if any loaded mesh has issues + setLegacyRigFlags(legacy_rig_flags); } //----------------------------------------------------------------------------- -// isRigLegacy() +// determineRigLegacyFlags() //----------------------------------------------------------------------------- -bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAsset ) +U32 LLModelLoader::determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset ) { //No joints in asset if ( jointListFromAsset.size() == 0 ) @@ -426,7 +425,12 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs { LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL; - return false; + LLSD args; + args["Message"] = "TooManyJoint"; + args["[JOINTS]"] = LLSD::Integer(jointListFromAsset.size()); + args["[MAX]"] = LLSD::Integer(mMaxJointsPerMesh); + mWarningsArray.append(args); + return LEGACY_RIG_FLAG_TOO_MANY_JOINTS; } // Unknown joints in asset @@ -437,16 +441,24 @@ bool LLModelLoader::isRigLegacy( const std::vector<std::string> &jointListFromAs if (mJointMap.find(*it)==mJointMap.end()) { LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL; + LLSD args; + args["Message"] = "UnrecognizedJoint"; + args["[NAME]"] = *it; + mWarningsArray.append(args); unknown_joint_count++; } } if (unknown_joint_count>0) { LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; - return false; + LLSD args; + args["Message"] = "UnknownJoints"; + args["[COUNT]"] = LLSD::Integer(unknown_joint_count); + mWarningsArray.append(args); + return LEGACY_RIG_FLAG_UNKNOWN_JOINT; } - return true; + return LEGACY_RIG_OK; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 643c45a6d8..fbc74554a0 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -42,6 +42,10 @@ typedef std::deque<std::string> JointNameSet; const S32 SLM_SUPPORTED_VERSION = 3; const S32 NUM_LOD = 4; +const U32 LEGACY_RIG_OK = 0; +const U32 LEGACY_RIG_FLAG_TOO_MANY_JOINTS = 1; +const U32 LEGACY_RIG_FLAG_UNKNOWN_JOINT = 2; + class LLModelLoader : public LLThread { public: @@ -166,7 +170,7 @@ public: void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); //Determines if a rig is a legacy from the joint list - bool isRigLegacy( const std::vector<std::string> &jointListFromAsset ); + U32 determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset ); //Determines if a rig is suitable for upload bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); @@ -174,8 +178,9 @@ public: const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } - const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } - void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; } + const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; } + U32 getLegacyRigFlags() const { return mLegacyRigFlags; } + void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; } //----------------------------------------------------------------------------- // isNodeAJoint() @@ -185,6 +190,9 @@ public: return name != NULL && mJointMap.find(name) != mJointMap.end(); } + const LLSD logOut() const { return mWarningsArray; } + void clearLog() { mWarningsArray.clear(); } + protected: LLModelLoader::load_callback_t mLoadCallback; @@ -194,13 +202,15 @@ protected: void* mOpaqueData; bool mRigValidJointUpload; - bool mLegacyRigValid; + U32 mLegacyRigFlags; bool mNoNormalize; bool mNoOptimize; JointTransformMap mJointTransformMap; + LLSD mWarningsArray; // preview floater will pull logs from here + static std::list<LLModelLoader*> sActiveLoaderList; static bool isAlive(LLModelLoader* loader) ; }; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index a0987b35d8..53b83a40d7 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1013,7 +1013,7 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa U64 exception_faces; U8 *start_loc = cur_ptr; - htonmemcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size); + htolememcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size); cur_ptr += data_size; for (face_index = last_face_index-1; face_index >= 0; face_index--) @@ -1072,7 +1072,7 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa *cur_ptr++ = (U8)(exception_faces & 0x7F); - htonmemcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size); + htolememcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size); cur_ptr += data_size; } } @@ -1083,7 +1083,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat { U8 *start_loc = cur_ptr; U64 i; - htonmemcpy(data_ptr,cur_ptr, type,data_size); + htolememcpy(data_ptr,cur_ptr, type,data_size); cur_ptr += data_size; for (i = 1; i < face_count; i++) @@ -1108,7 +1108,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat { if (i & 0x01) { - htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size); + htolememcpy(data_ptr+(j*data_size),cur_ptr,type,data_size); LL_DEBUGS("TEFieldDecode") << "Assigning " ; char foo[64]; sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); @@ -1659,7 +1659,7 @@ BOOL LLLightParams::unpack(LLDataPacker &dp) { LLColor4U color; dp.unpackColor4U(color, "color"); - setColor(LLColor4(color)); + setLinearColor(LLColor4(color)); F32 radius; dp.unpackF32(radius, "radius"); @@ -1707,7 +1707,7 @@ LLSD LLLightParams::asLLSD() const { LLSD sd; - sd["color"] = ll_sd_from_color4(getColor()); + sd["color"] = ll_sd_from_color4(getLinearColor()); sd["radius"] = getRadius(); sd["falloff"] = getFalloff(); sd["cutoff"] = getCutoff(); @@ -1721,7 +1721,7 @@ bool LLLightParams::fromLLSD(LLSD& sd) w = "color"; if (sd.has(w)) { - setColor( ll_color4_from_sd(sd["color"]) ); + setLinearColor( ll_color4_from_sd(sd["color"]) ); } else goto fail; w = "radius"; if (sd.has(w)) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 6fd433c337..b1f8112223 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -131,8 +131,8 @@ extern const F32 LIGHT_MAX_CUTOFF; class LLLightParams : public LLNetworkData { -protected: - LLColor4 mColor; // alpha = intensity +private: + LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity F32 mRadius; F32 mFalloff; F32 mCutoff; @@ -149,13 +149,22 @@ public: operator LLSD() const { return asLLSD(); } bool fromLLSD(LLSD& sd); - - void setColor(const LLColor4& color) { mColor = color; mColor.clamp(); } + // set the color by gamma corrected color value + // color - gamma corrected color value (directly taken from an on-screen color swatch) + void setSRGBColor(const LLColor4& color) { setLinearColor(linearColor4(color)); } + + // set the color by linear color value + // color - linear color value (value as it appears in shaders) + void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); } void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); } void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); } void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); } - LLColor4 getColor() const { return mColor; } + // get the linear space color of this light. This value can be fed directly to shaders + LLColor4 getLinearColor() const { return mColor; } + // get the sRGB (gamma corrected) color of this light, this is the value that should be displayed in the UI + LLColor4 getSRGBColor() const { return srgbColor4(mColor); } + F32 getRadius() const { return mRadius; } F32 getFalloff() const { return mFalloff; } F32 getCutoff() const { return mCutoff; } diff --git a/indra/llprimitive/lltextureanim.cpp b/indra/llprimitive/lltextureanim.cpp index 031a315d62..7c48e57a1a 100644 --- a/indra/llprimitive/lltextureanim.cpp +++ b/indra/llprimitive/lltextureanim.cpp @@ -94,9 +94,9 @@ void LLTextureAnim::packTAMessage(LLMessageSystem *mesgsys) const data[1] = mFace; data[2] = mSizeX; data[3] = mSizeY; - htonmemcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); - htonmemcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); - htonmemcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); + htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); + htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); + htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); mesgsys->addBinaryDataFast(_PREHASH_TextureAnim, data, TA_BLOCK_SIZE); } @@ -109,9 +109,9 @@ void LLTextureAnim::packTAMessage(LLDataPacker &dp) const data[1] = mFace; data[2] = mSizeX; data[3] = mSizeY; - htonmemcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); - htonmemcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); - htonmemcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); + htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); + htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); + htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); dp.packBinaryData(data, TA_BLOCK_SIZE, "TextureAnimation"); } @@ -146,9 +146,9 @@ void LLTextureAnim::unpackTAMessage(LLMessageSystem *mesgsys, const S32 block_nu mSizeX = llmax((U8)1, data[2]); mSizeY = llmax((U8)1, data[3]); } - htonmemcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); - htonmemcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); - htonmemcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); + htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); + htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); + htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); } void LLTextureAnim::unpackTAMessage(LLDataPacker &dp) @@ -170,9 +170,9 @@ void LLTextureAnim::unpackTAMessage(LLDataPacker &dp) mFace = data[1]; mSizeX = data[2]; mSizeY = data[3]; - htonmemcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); - htonmemcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); - htonmemcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); + htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); + htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); + htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); } LLSD LLTextureAnim::asLLSD() const |