summaryrefslogtreecommitdiff
path: root/indra/llprimitive
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llprimitive')
-rw-r--r--indra/llprimitive/CMakeLists.txt2
-rw-r--r--indra/llprimitive/lldaeloader.cpp144
-rw-r--r--indra/llprimitive/lldaeloader.h2
-rw-r--r--indra/llprimitive/llmodel.cpp32
-rw-r--r--indra/llprimitive/llmodelloader.cpp38
-rw-r--r--indra/llprimitive/llmodelloader.h18
-rw-r--r--indra/llprimitive/llprimitive.cpp14
-rw-r--r--indra/llprimitive/llprimitive.h19
-rw-r--r--indra/llprimitive/lltextureanim.cpp24
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