Prep for animesh.
This commit is contained in:
@@ -236,6 +236,14 @@
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
|
||||
<key>ObjectAnimation</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>template</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
|
||||
<key>AvatarAppearance</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
|
||||
@@ -185,8 +185,9 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
|
||||
mHeadOffset(),
|
||||
mRoot(NULL),
|
||||
mWearableData(wearable_data),
|
||||
mNumBones(0),
|
||||
mIsBuilt(FALSE)
|
||||
mNumBones(0),
|
||||
mIsBuilt(FALSE),
|
||||
mInitFlags(0)
|
||||
{
|
||||
llassert_always(mWearableData);
|
||||
mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
|
||||
@@ -282,6 +283,8 @@ void LLAvatarAppearance::initInstance()
|
||||
}
|
||||
buildCharacter();
|
||||
|
||||
mInitFlags |= 1<<0;
|
||||
|
||||
}
|
||||
|
||||
// virtual
|
||||
@@ -1370,12 +1373,12 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of
|
||||
//-----------------------------------------------------------------------------
|
||||
// findCollisionVolume()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
|
||||
LLJoint* LLAvatarAppearance::findCollisionVolume(S32 volume_id)
|
||||
{
|
||||
//SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32
|
||||
//to compare we also need to be sure of the wrap around case producing (S32) <0
|
||||
//or in terms of the U32 an out of bounds index in the array.
|
||||
if ((S32)volume_id > (S32)mCollisionVolumes.size() || (S32)volume_id<0)
|
||||
if ((S32)volume_id > (S32)mCollisionVolumes.size() || volume_id<0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -1828,13 +1831,34 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases
|
||||
{
|
||||
|
||||
LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
|
||||
for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); iter != sAvatarSkeletonInfo->mBoneInfoList.end(); ++iter)
|
||||
for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin();
|
||||
iter != sAvatarSkeletonInfo->mBoneInfoList.end();
|
||||
++iter)
|
||||
{
|
||||
//LLAvatarBoneInfo *bone_info = *iter;
|
||||
makeJointAliases( *iter );
|
||||
}
|
||||
|
||||
LLAvatarXmlInfo::attachment_info_list_t::iterator attach_iter;
|
||||
for (attach_iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
|
||||
attach_iter != sAvatarXmlInfo->mAttachmentInfoList.end();
|
||||
++attach_iter)
|
||||
{
|
||||
LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *attach_iter;
|
||||
std::string bone_name = info->mName;
|
||||
|
||||
// Also accept the name with spaces substituted with
|
||||
// underscores. This gives a mechanism for referencing such joints
|
||||
// in daes, which don't allow spaces.
|
||||
std::string sub_space_to_underscore = bone_name;
|
||||
LLStringUtil::replaceChar(sub_space_to_underscore, ' ', '_');
|
||||
if (sub_space_to_underscore != bone_name)
|
||||
{
|
||||
mJointAliasMap[sub_space_to_underscore] = bone_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return mJointAliasMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
static void initClass(); // initializes static members
|
||||
static void cleanupClass(); // Cleanup data that's only init'd once per class.
|
||||
virtual void initInstance(); // Called after construction to initialize the instance.
|
||||
S32 mInitFlags;
|
||||
virtual BOOL loadSkeletonNode();
|
||||
BOOL loadMeshNodes();
|
||||
BOOL loadLayersets();
|
||||
@@ -93,7 +94,7 @@ public:
|
||||
|
||||
/*virtual*/ const char* getAnimationPrefix() { return "avatar"; }
|
||||
/*virtual*/ LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
|
||||
/*virtual*/ LLJoint* findCollisionVolume(U32 volume_id);
|
||||
/*virtual*/ LLJoint* findCollisionVolume(S32 volume_id);
|
||||
/*virtual*/ S32 getCollisionVolumeID(std::string &name);
|
||||
/*virtual*/ LLPolyMesh* getHeadMesh();
|
||||
/*virtual*/ LLPolyMesh* getUpperBodyMesh();
|
||||
@@ -234,7 +235,7 @@ protected:
|
||||
** RENDERING
|
||||
**/
|
||||
public:
|
||||
BOOL mIsDummy; // for special views
|
||||
BOOL mIsDummy; // for special views and animated object controllers; local to viewer
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Morph masks
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
|
||||
virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset) { return LLVector3::zero; }
|
||||
|
||||
virtual LLJoint* findCollisionVolume(U32 volume_id) { return NULL; }
|
||||
virtual LLJoint* findCollisionVolume(S32 volume_id) { return NULL; }
|
||||
|
||||
virtual S32 getCollisionVolumeID(std::string &name) { return -1; }
|
||||
|
||||
|
||||
@@ -69,6 +69,17 @@ public:
|
||||
private:
|
||||
map_type m_map;
|
||||
};
|
||||
|
||||
inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b)
|
||||
{
|
||||
return a.getMap() == b.getMap();
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class LLJoint
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -623,7 +623,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
|
||||
|
||||
LLDataPackerBinaryBuffer dp(anim_data, anim_file_size);
|
||||
|
||||
if (!deserialize(dp))
|
||||
if (!deserialize(dp, getID()))
|
||||
{
|
||||
LL_WARNS() << "Failed to decode asset for animation " << getName() << ":" << getID() << LL_ENDL;
|
||||
mAssetStatus = ASSET_FETCH_FAILED;
|
||||
@@ -1291,7 +1291,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
|
||||
//-----------------------------------------------------------------------------
|
||||
// deserialize()
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
{
|
||||
BOOL old_version = FALSE;
|
||||
|
||||
@@ -1324,13 +1324,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if (!dp.unpackU16(version, "version"))
|
||||
{
|
||||
LL_WARNS() << "can't read version number" << LL_ENDL;
|
||||
LL_WARNS() << "can't read version number for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackU16(sub_version, "sub_version"))
|
||||
{
|
||||
LL_WARNS() << "can't read sub version number" << LL_ENDL;
|
||||
LL_WARNS() << "can't read sub version number for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1341,28 +1341,32 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
else if (version != KEYFRAME_MOTION_VERSION || sub_version != KEYFRAME_MOTION_SUBVERSION)
|
||||
{
|
||||
#if LL_RELEASE
|
||||
LL_WARNS() << "Bad animation version " << version << "." << sub_version << LL_ENDL;
|
||||
LL_WARNS() << "Bad animation version " << version << "." << sub_version
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
#else
|
||||
LL_ERRS() << "Bad animation version " << version << "." << sub_version << LL_ENDL;
|
||||
LL_ERRS() << "Bad animation version " << version << "." << sub_version
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!dp.unpackS32(temp_priority, "base_priority"))
|
||||
{
|
||||
LL_WARNS() << "can't read animation base_priority" << LL_ENDL;
|
||||
LL_WARNS() << "can't read animation base_priority"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
|
||||
|
||||
if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
|
||||
{
|
||||
mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1);
|
||||
mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1);
|
||||
mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
|
||||
}
|
||||
else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
|
||||
{
|
||||
LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority << LL_ENDL;
|
||||
LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1371,14 +1375,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
//-------------------------------------------------------------------------
|
||||
if (!dp.unpackF32(mJointMotionList->mDuration, "duration"))
|
||||
{
|
||||
LL_WARNS() << "can't read duration" << LL_ENDL;
|
||||
LL_WARNS() << "can't read duration"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mJointMotionList->mDuration > MAX_ANIM_DURATION ||
|
||||
!std::isfinite(mJointMotionList->mDuration))
|
||||
{
|
||||
LL_WARNS() << "invalid animation duration" << LL_ENDL;
|
||||
LL_WARNS() << "invalid animation duration"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1387,13 +1393,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
//-------------------------------------------------------------------------
|
||||
if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name"))
|
||||
{
|
||||
LL_WARNS() << "can't read optional_emote_animation" << LL_ENDL;
|
||||
LL_WARNS() << "can't read optional_emote_animation"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(mJointMotionList->mEmoteName==mID.asString())
|
||||
{
|
||||
LL_WARNS() << "Malformed animation mEmoteName==mID" << LL_ENDL;
|
||||
LL_WARNS() << "Malformed animation mEmoteName==mID"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1403,20 +1411,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") ||
|
||||
!std::isfinite(mJointMotionList->mLoopInPoint))
|
||||
{
|
||||
LL_WARNS() << "can't read loop point" << LL_ENDL;
|
||||
LL_WARNS() << "can't read loop point"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") ||
|
||||
!std::isfinite(mJointMotionList->mLoopOutPoint))
|
||||
{
|
||||
LL_WARNS() << "can't read loop point" << LL_ENDL;
|
||||
LL_WARNS() << "can't read loop point"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackS32(mJointMotionList->mLoop, "loop"))
|
||||
{
|
||||
LL_WARNS() << "can't read loop" << LL_ENDL;
|
||||
LL_WARNS() << "can't read loop"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1426,14 +1437,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") ||
|
||||
!std::isfinite(mJointMotionList->mEaseInDuration))
|
||||
{
|
||||
LL_WARNS() << "can't read easeIn" << LL_ENDL;
|
||||
LL_WARNS() << "can't read easeIn"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") ||
|
||||
!std::isfinite(mJointMotionList->mEaseOutDuration))
|
||||
{
|
||||
LL_WARNS() << "can't read easeOut" << LL_ENDL;
|
||||
LL_WARNS() << "can't read easeOut"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1443,13 +1456,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
U32 word;
|
||||
if (!dp.unpackU32(word, "hand_pose"))
|
||||
{
|
||||
LL_WARNS() << "can't read hand pose" << LL_ENDL;
|
||||
LL_WARNS() << "can't read hand pose"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(word > LLHandMotion::NUM_HAND_POSES)
|
||||
{
|
||||
LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word << LL_ENDL;
|
||||
LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1461,18 +1476,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
U32 num_motions = 0;
|
||||
if (!dp.unpackU32(num_motions, "num_joints"))
|
||||
{
|
||||
LL_WARNS() << "can't read number of joints" << LL_ENDL;
|
||||
LL_WARNS() << "can't read number of joints"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num_motions == 0)
|
||||
{
|
||||
LL_WARNS() << "no joints in animation" << LL_ENDL;
|
||||
LL_WARNS() << "no joints"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS)
|
||||
{
|
||||
LL_WARNS() << "too many joints in animation" << LL_ENDL;
|
||||
LL_WARNS() << "too many joints"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1500,13 +1518,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
std::string joint_name;
|
||||
if (!dp.unpackString(joint_name, "joint_name"))
|
||||
{
|
||||
LL_WARNS() << "can't read joint name" << LL_ENDL;
|
||||
LL_WARNS() << "can't read joint name"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (joint_name == "mScreen" || joint_name == "mRoot")
|
||||
{
|
||||
LL_WARNS() << "attempted to animate special " << joint_name << " joint" << LL_ENDL;
|
||||
LL_WARNS() << "attempted to animate special " << joint_name << " joint"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1520,10 +1540,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
// LL_INFOS() << " joint: " << joint_name << LL_ENDL;
|
||||
if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0))
|
||||
{
|
||||
LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num << " is outside of legal range [0-"
|
||||
<< LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << joint->getName() << LL_ENDL;
|
||||
joint = NULL;
|
||||
}
|
||||
LL_WARNS() << "Joint will be omitted from animation: joint_num " << joint_num
|
||||
<< " is outside of legal range [0-"
|
||||
<< LL_CHARACTER_MAX_ANIMATED_JOINTS << ") for joint " << joint->getName()
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
joint = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1539,7 +1561,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
i++;
|
||||
}
|
||||
// </edit>
|
||||
LL_WARNS() << "joint not found: " << joint_name << LL_ENDL;
|
||||
LL_WARNS() << "invalid joint name: " << joint_name
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
//return FALSE;
|
||||
}
|
||||
|
||||
@@ -1556,13 +1579,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
S32 joint_priority;
|
||||
if (!dp.unpackS32(joint_priority, "joint_priority"))
|
||||
{
|
||||
LL_WARNS() << "can't read joint priority." << LL_ENDL;
|
||||
LL_WARNS() << "can't read joint priority."
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (joint_priority < LLJoint::USE_MOTION_PRIORITY)
|
||||
{
|
||||
LL_WARNS() << "joint priority unknown - too low." << LL_ENDL;
|
||||
LL_WARNS() << "joint priority unknown - too low."
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1580,7 +1605,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
//---------------------------------------------------------------------
|
||||
if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0)
|
||||
{
|
||||
LL_WARNS() << "can't read number of rotation keys" << LL_ENDL;
|
||||
LL_WARNS() << "can't read number of rotation keys"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1605,7 +1631,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
if (!dp.unpackF32(time, "time") ||
|
||||
!std::isfinite(time))
|
||||
{
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1614,7 +1641,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
{
|
||||
if (!dp.unpackU16(time_short, "time"))
|
||||
{
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1622,7 +1650,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if (time < 0 || time > mJointMotionList->mDuration)
|
||||
{
|
||||
LL_WARNS() << "invalid frame time" << LL_ENDL;
|
||||
LL_WARNS() << "invalid frame time"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1656,13 +1685,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if( !(rot_key.mRotation.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite angle in rotation key" << LL_ENDL;
|
||||
LL_WARNS() << "non-finite angle in rotation key"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read rotation key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1674,7 +1705,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
//---------------------------------------------------------------------
|
||||
if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0)
|
||||
{
|
||||
LL_WARNS() << "can't read number of position keys" << LL_ENDL;
|
||||
LL_WARNS() << "can't read number of position keys"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1699,7 +1731,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
if (!dp.unpackF32(pos_key.mTime, "time") ||
|
||||
!std::isfinite(pos_key.mTime))
|
||||
{
|
||||
LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read position key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1707,7 +1740,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
{
|
||||
if (!dp.unpackU16(time_short, "time"))
|
||||
{
|
||||
LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read position key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1741,13 +1775,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if( !(pos_key.mPosition.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite position in key" << LL_ENDL;
|
||||
LL_WARNS() << "non-finite position in key"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
LL_WARNS() << "can't read position key (" << k << ")" << LL_ENDL;
|
||||
LL_WARNS() << "can't read position key (" << k << ")"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1768,13 +1804,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
S32 num_constraints = 0;
|
||||
if (!dp.unpackS32(num_constraints, "num_constraints"))
|
||||
{
|
||||
LL_WARNS() << "can't read number of constraints" << LL_ENDL;
|
||||
LL_WARNS() << "can't read number of constraints"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0)
|
||||
{
|
||||
LL_WARNS() << "Bad number of constraints... ignoring: " << num_constraints << LL_ENDL;
|
||||
LL_WARNS() << "Bad number of constraints... ignoring: " << num_constraints
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1791,26 +1829,30 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if (!dp.unpackU8(byte, "chain_length"))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint chain length" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint chain length"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
constraintp->mChainLength = (S32) byte;
|
||||
|
||||
if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions())
|
||||
{
|
||||
LL_WARNS() << "invalid constraint chain length" << LL_ENDL;
|
||||
LL_WARNS() << "invalid constraint chain length"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackU8(byte, "constraint_type"))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint type" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint type"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( byte >= NUM_CONSTRAINT_TYPES )
|
||||
{
|
||||
LL_WARNS() << "invalid constraint type" << LL_ENDL;
|
||||
LL_WARNS() << "invalid constraint type"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
constraintp->mConstraintType = (EConstraintType)byte;
|
||||
@@ -1819,37 +1861,39 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
U8 bin_data[BIN_DATA_LENGTH+1];
|
||||
if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume"))
|
||||
{
|
||||
LL_WARNS() << "can't read source volume name" << LL_ENDL;
|
||||
LL_WARNS() << "can't read source volume name"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
|
||||
str = (char*)bin_data;
|
||||
constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
|
||||
|
||||
// <edit>
|
||||
if(constraintp->mSourceConstraintVolume == -1)
|
||||
if (constraintp->mSourceConstraintVolume == -1)
|
||||
{
|
||||
LL_WARNS() << "can't get source constraint volume" << LL_ENDL;
|
||||
LL_WARNS() << "not a valid source constraint volume " << str
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset"))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint source offset" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint source offset"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !(constraintp->mSourceConstraintOffset.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite constraint source offset" << LL_ENDL;
|
||||
LL_WARNS() << "non-finite constraint source offset"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume"))
|
||||
{
|
||||
LL_WARNS() << "can't read target volume name" << LL_ENDL;
|
||||
LL_WARNS() << "can't read target volume name"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1864,29 +1908,39 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
{
|
||||
constraintp->mConstraintTargetType = CONSTRAINT_TARGET_TYPE_BODY;
|
||||
constraintp->mTargetConstraintVolume = mCharacter->getCollisionVolumeID(str);
|
||||
if (constraintp->mTargetConstraintVolume == -1)
|
||||
{
|
||||
LL_WARNS() << "not a valid target constraint volume " << str
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset"))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint target offset" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint target offset"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !(constraintp->mTargetConstraintOffset.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite constraint target offset" << LL_ENDL;
|
||||
LL_WARNS() << "non-finite constraint target offset"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir"))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint target direction" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint target direction"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !(constraintp->mTargetConstraintDir.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite constraint target direction" << LL_ENDL;
|
||||
LL_WARNS() << "non-finite constraint target direction"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1898,25 +1952,29 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !std::isfinite(constraintp->mEaseInStartTime))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint ease in start time" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint ease in start time"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !std::isfinite(constraintp->mEaseInStopTime))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint ease in stop time" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint ease in stop time"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !std::isfinite(constraintp->mEaseOutStartTime))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint ease out start time" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint ease out start time"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !std::isfinite(constraintp->mEaseOutStopTime))
|
||||
{
|
||||
LL_WARNS() << "can't read constraint ease out stop time" << LL_ENDL;
|
||||
LL_WARNS() << "can't read constraint ease out stop time"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1939,7 +1997,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
if (!parent)
|
||||
{
|
||||
LL_WARNS() << "Joint with no parent: " << joint->getName()
|
||||
<< " Emote: " << mJointMotionList->mEmoteName << LL_ENDL;
|
||||
<< " Emote: " << mJointMotionList->mEmoteName
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
joint = parent;
|
||||
@@ -1950,7 +2009,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
|
||||
if ( !constraint_joint )
|
||||
{
|
||||
LL_WARNS() << "Invalid joint " << j << LL_ENDL;
|
||||
LL_WARNS() << "Invalid joint " << j
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1962,7 +2022,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
|
||||
}
|
||||
if (constraintp->mJointStateIndices[i] < 0 )
|
||||
{
|
||||
LL_WARNS() << "No joint index for constraint " << i << LL_ENDL;
|
||||
LL_WARNS() << "No joint index for constraint " << i
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -2318,7 +2379,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
|
||||
LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL;
|
||||
|
||||
LLDataPackerBinaryBuffer dp(buffer, size);
|
||||
if (motionp->deserialize(dp))
|
||||
if (motionp->deserialize(dp, asset_uuid))
|
||||
{
|
||||
motionp->mAssetStatus = ASSET_LOADED;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
public:
|
||||
U32 getFileSize();
|
||||
BOOL serialize(LLDataPacker& dp) const;
|
||||
BOOL deserialize(LLDataPacker& dp);
|
||||
BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id);
|
||||
BOOL isLoaded() { return !!mJointMotionList; }
|
||||
|
||||
|
||||
|
||||
@@ -126,22 +126,22 @@ LLMotion* LLMotionRegistry::createMotion(LLUUID const& id, LLMotionController* c
|
||||
// Class Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LLMotionController::LLMotionController()
|
||||
: mIsSelf(FALSE),
|
||||
mTimeFactor(sCurrentTimeFactor),
|
||||
: mTimeFactor(sCurrentTimeFactor),
|
||||
mCharacter(NULL),
|
||||
mAnimTime(0.f),
|
||||
mActiveMask(0),
|
||||
mDisableSyncing(0),
|
||||
mHidden(false),
|
||||
mHaveVisibleSyncedMotions(false),
|
||||
mPrevTimerElapsed(0.f),
|
||||
mAnimTime(0.f),
|
||||
mLastTime(0.0f),
|
||||
mHasRunOnce(FALSE),
|
||||
mPaused(FALSE),
|
||||
mPauseTime(0.f),
|
||||
mPausedFrame(0),
|
||||
mTimeStep(0.f),
|
||||
mTimeStepCount(0),
|
||||
mLastInterp(0.f)
|
||||
mLastInterp(0.f),
|
||||
mIsSelf(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
|
||||
{
|
||||
// if already inactive, return false
|
||||
LLMotion *motion = findMotion(id);
|
||||
return stopMotionInstance(motion, stop_immediate);
|
||||
return stopMotionInstance(motion, stop_immediate||mPaused);
|
||||
}
|
||||
|
||||
BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate)
|
||||
@@ -1312,6 +1312,7 @@ void LLMotionController::pauseAllMotions()
|
||||
{
|
||||
//LL_INFOS() << "Pausing animations..." << LL_ENDL;
|
||||
mPaused = TRUE;
|
||||
mPausedFrame = LLFrameTimer::getFrameCount();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -162,16 +162,20 @@ public:
|
||||
void pauseAllMotions();
|
||||
void unpauseAllMotions();
|
||||
BOOL isPaused() const { return mPaused; }
|
||||
S32 getPausedFrame() const { return mPausedFrame; }
|
||||
//<singu>
|
||||
void requestPause(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
|
||||
void pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
|
||||
//</singu>
|
||||
|
||||
void setTimeStep(F32 step);
|
||||
F32 getTimeStep() const { return mTimeStep; }
|
||||
|
||||
void setTimeFactor(F32 time_factor);
|
||||
F32 getTimeFactor() const { return mTimeFactor; }
|
||||
|
||||
F32 getAnimTime() const { return mAnimTime; }
|
||||
|
||||
motion_list_t& getActiveMotions() { return mActiveMotions; }
|
||||
|
||||
void incMotionCounts(S32& num_motions, S32& num_loading_motions, S32& num_loaded_motions, S32& num_active_motions, S32& num_deprecated_motions);
|
||||
@@ -248,7 +252,7 @@ protected:
|
||||
F32 mLastTime;
|
||||
BOOL mHasRunOnce;
|
||||
BOOL mPaused;
|
||||
F32 mPauseTime;
|
||||
S32 mPausedFrame;
|
||||
F32 mTimeStep;
|
||||
S32 mTimeStepCount;
|
||||
F32 mLastInterp;
|
||||
@@ -263,7 +267,6 @@ public:
|
||||
bool syncing_disabled(void) const { return mDisableSyncing >= 100; }
|
||||
|
||||
// Accessors needed for synchronization.
|
||||
F32 getAnimTime(void) const { return mAnimTime; }
|
||||
bool isHidden(void) const { return mHidden; }
|
||||
|
||||
// Called often. Should return false if we still need to keep updating our motions even if we're not visible.
|
||||
|
||||
@@ -22,6 +22,7 @@ set(llmath_SOURCE_FILES
|
||||
llperlin.cpp
|
||||
llquaternion.cpp
|
||||
llrect.cpp
|
||||
llrigginginfo.cpp
|
||||
llsdutil_math.cpp
|
||||
llsphere.cpp
|
||||
llvector4a.cpp
|
||||
@@ -67,6 +68,7 @@ set(llmath_HEADER_FILES
|
||||
llquaternion2.h
|
||||
llquaternion2.inl
|
||||
llrect.h
|
||||
llrigginginfo.h
|
||||
llsdutil_math.h
|
||||
llsimdmath.h
|
||||
llsimdtypes.h
|
||||
|
||||
@@ -700,4 +700,12 @@ public:
|
||||
}
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)
|
||||
{
|
||||
s << "[" << m.getF32ptr()[0] << ", " << m.getF32ptr()[1] << ", " << m.getF32ptr()[2] << ", " << m.getF32ptr()[3] << "]";
|
||||
return s;
|
||||
}
|
||||
|
||||
void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents);
|
||||
#endif
|
||||
|
||||
@@ -336,4 +336,9 @@ inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p
|
||||
max.setMax(max, p);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v)
|
||||
{
|
||||
s << "(" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ")";
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1301,7 +1301,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff
|
||||
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
|
||||
{
|
||||
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
|
||||
const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
|
||||
static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
|
||||
|
||||
F32 revolutions = params.getRevolutions();
|
||||
F32 skew = params.getSkew();
|
||||
@@ -1599,6 +1599,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
|
||||
if (is_sculpted)
|
||||
sides = llmax(sculpt_size, 1);
|
||||
|
||||
if (0 < sides)
|
||||
genNGon(params, sides);
|
||||
}
|
||||
break;
|
||||
@@ -2081,6 +2082,7 @@ void LLVolume::resizePath(S32 length)
|
||||
{
|
||||
mPathp->resizePath(length);
|
||||
mVolumeFaces.clear();
|
||||
setDirty();
|
||||
}
|
||||
|
||||
void LLVolume::regen()
|
||||
@@ -2138,19 +2140,22 @@ BOOL LLVolume::generate()
|
||||
|
||||
F32 profile_detail = mDetail;
|
||||
F32 path_detail = mDetail;
|
||||
|
||||
U8 path_type = mParams.getPathParams().getCurveType();
|
||||
U8 profile_type = mParams.getProfileParams().getCurveType();
|
||||
|
||||
if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
|
||||
{ //cylinders don't care about Z-Axis
|
||||
mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
|
||||
|
||||
if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
U8 path_type = mParams.getPathParams().getCurveType();
|
||||
U8 profile_type = mParams.getProfileParams().getCurveType();
|
||||
if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
|
||||
{
|
||||
//cylinders don't care about Z-Axis
|
||||
mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
|
||||
}
|
||||
else if (path_type == LL_PCODE_PATH_CIRCLE)
|
||||
{
|
||||
mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
|
||||
}
|
||||
}
|
||||
else if (path_type == LL_PCODE_PATH_CIRCLE)
|
||||
{
|
||||
mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
|
||||
}
|
||||
|
||||
|
||||
BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
|
||||
BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
|
||||
|
||||
@@ -2906,15 +2911,41 @@ F32 LLVolume::sculptGetSurfaceArea()
|
||||
return area;
|
||||
}
|
||||
|
||||
// create placeholder shape
|
||||
void LLVolume::sculptGeneratePlaceholder()
|
||||
// create empty placeholder shape
|
||||
void LLVolume::sculptGenerateEmptyPlaceholder()
|
||||
{
|
||||
S32 sizeS = mPathp->mPath.size();
|
||||
S32 sizeT = mProfilep->mProfile.size();
|
||||
|
||||
|
||||
S32 line = 0;
|
||||
|
||||
for (S32 s = 0; s < sizeS; s++)
|
||||
{
|
||||
for (S32 t = 0; t < sizeT; t++)
|
||||
{
|
||||
S32 i = t + line;
|
||||
LLVector4a& pt = mMesh[i];
|
||||
|
||||
F32* p = pt.getF32ptr();
|
||||
|
||||
p[0] = 0;
|
||||
p[1] = 0;
|
||||
p[2] = 0;
|
||||
|
||||
llassert(pt.isFinite3());
|
||||
}
|
||||
line += sizeT;
|
||||
}
|
||||
}
|
||||
|
||||
// create sphere placeholder shape
|
||||
void LLVolume::sculptGenerateSpherePlaceholder()
|
||||
{
|
||||
S32 sizeS = mPathp->mPath.size();
|
||||
S32 sizeT = mProfilep->mProfile.size();
|
||||
|
||||
S32 line = 0;
|
||||
|
||||
// for now, this is a sphere.
|
||||
for (S32 s = 0; s < sizeS; s++)
|
||||
{
|
||||
for (S32 t = 0; t < sizeT; t++)
|
||||
@@ -3123,7 +3154,7 @@ bool sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32
|
||||
}
|
||||
|
||||
// sculpt replaces generate() for sculpted surfaces
|
||||
void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level)
|
||||
void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)
|
||||
{
|
||||
U8 sculpt_type = mParams.getSculptType();
|
||||
|
||||
@@ -3187,13 +3218,22 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
|
||||
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
|
||||
{
|
||||
data_is_empty = TRUE;
|
||||
visible_placeholder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data_is_empty)
|
||||
{
|
||||
sculptGeneratePlaceholder();
|
||||
if (visible_placeholder)
|
||||
{
|
||||
// Object should be visible since there will be nothing else to display
|
||||
sculptGenerateSpherePlaceholder();
|
||||
}
|
||||
else
|
||||
{
|
||||
sculptGenerateEmptyPlaceholder();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3723,10 +3763,46 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
|
||||
if (face.mTypeMask & (LLVolumeFace::CAP_MASK))
|
||||
{
|
||||
LLVector4a* v = (LLVector4a*)face.mPositions;
|
||||
LLVector4a* n = (LLVector4a*)face.mNormals;
|
||||
|
||||
for (U32 j = 0; j < (U32)face.mNumIndices / 3; j++)
|
||||
{
|
||||
for (S32 k = 0; k < 3; k++)
|
||||
{
|
||||
S32 index = face.mEdge[j * 3 + k];
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
// silhouette edge, currently only cubes, so no other conditions
|
||||
|
||||
S32 v1 = face.mIndices[j * 3 + k];
|
||||
S32 v2 = face.mIndices[j * 3 + ((k + 1) % 3)];
|
||||
|
||||
LLVector4a t;
|
||||
mat.affineTransform(v[v1], t);
|
||||
vertices.push_back(LLVector3(t[0], t[1], t[2]));
|
||||
|
||||
norm_mat.rotate(n[v1], t);
|
||||
|
||||
t.normalize3fast();
|
||||
normals.push_back(LLVector3(t[0], t[1], t[2]));
|
||||
|
||||
mat.affineTransform(v[v2], t);
|
||||
vertices.push_back(LLVector3(t[0], t[1], t[2]));
|
||||
|
||||
norm_mat.rotate(n[v2], t);
|
||||
t.normalize3fast();
|
||||
normals.push_back(LLVector3(t[0], t[1], t[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
|
||||
//==============================================
|
||||
//DEBUG draw edge map instead of silhouette edge
|
||||
@@ -4709,6 +4785,7 @@ LLVolumeFace::~LLVolumeFace()
|
||||
{
|
||||
ll_aligned_free_16(mExtents);
|
||||
mExtents = NULL;
|
||||
mCenter = NULL;
|
||||
|
||||
freeData();
|
||||
}
|
||||
@@ -5556,10 +5633,17 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
|
||||
if (!partial_build)
|
||||
{
|
||||
resizeIndices(grid_size*grid_size*6);
|
||||
if (!volume->isMeshAssetLoaded())
|
||||
{
|
||||
mEdge.resize(grid_size*grid_size * 6);
|
||||
}
|
||||
|
||||
U16* out = mIndices;
|
||||
|
||||
S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
|
||||
|
||||
int cur_edge = 0;
|
||||
|
||||
for(S32 gx = 0;gx<grid_size;gx++)
|
||||
{
|
||||
|
||||
@@ -5570,7 +5654,49 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
|
||||
for(S32 i=5;i>=0;i--)
|
||||
{
|
||||
*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1; // Mark face to higlight it
|
||||
}
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5578,6 +5704,48 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
|
||||
{
|
||||
*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
|
||||
}
|
||||
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6056,6 +6224,9 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
|
||||
allocateTangents(0);
|
||||
allocateVertices(num_verts);
|
||||
mNumVertices = num_verts;
|
||||
|
||||
// Force update
|
||||
mJointRiggingInfoTab.clear();
|
||||
}
|
||||
|
||||
void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)
|
||||
@@ -6201,78 +6372,6 @@ void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v,
|
||||
}
|
||||
}
|
||||
|
||||
void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in)
|
||||
{
|
||||
U16 offset = mNumVertices;
|
||||
|
||||
S32 new_count = face.mNumVertices + mNumVertices;
|
||||
|
||||
if (new_count > 65536)
|
||||
{
|
||||
LL_ERRS() << "Cannot append face -- 16-bit overflow will occur." << LL_ENDL;
|
||||
}
|
||||
|
||||
if (face.mNumVertices == 0)
|
||||
{
|
||||
LL_ERRS() << "Cannot append empty face." << LL_ENDL;
|
||||
}
|
||||
|
||||
allocateVertices(new_count, true);
|
||||
mNumVertices = new_count;
|
||||
|
||||
//get destination address of appended face
|
||||
LLVector4a* dst_pos = mPositions+offset;
|
||||
LLVector2* dst_tc = mTexCoords+offset;
|
||||
LLVector4a* dst_norm = mNormals+offset;
|
||||
|
||||
//get source addresses of appended face
|
||||
const LLVector4a* src_pos = face.mPositions;
|
||||
const LLVector2* src_tc = face.mTexCoords;
|
||||
const LLVector4a* src_norm = face.mNormals;
|
||||
|
||||
//load aligned matrices
|
||||
LLMatrix4a mat, norm_mat;
|
||||
mat.loadu(mat_in);
|
||||
norm_mat.loadu(norm_mat_in);
|
||||
|
||||
for (U32 i = 0; i < (U32)face.mNumVertices; ++i)
|
||||
{
|
||||
//transform appended face position and store
|
||||
mat.affineTransform(src_pos[i], dst_pos[i]);
|
||||
|
||||
//transform appended face normal and store
|
||||
norm_mat.rotate(src_norm[i], dst_norm[i]);
|
||||
dst_norm[i].normalize3fast();
|
||||
|
||||
//copy appended face texture coordinate
|
||||
dst_tc[i] = src_tc[i];
|
||||
|
||||
if (offset == 0 && i == 0)
|
||||
{ //initialize bounding box
|
||||
mExtents[0] = mExtents[1] = dst_pos[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
//stretch bounding box
|
||||
update_min_max(mExtents[0], mExtents[1], dst_pos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new_count = mNumIndices + face.mNumIndices;
|
||||
|
||||
allocateIndices(mNumIndices + face.mNumIndices, true);
|
||||
|
||||
//get destination address into new index buffer
|
||||
U16* dst_idx = mIndices+mNumIndices;
|
||||
mNumIndices = new_count;
|
||||
|
||||
for (U32 i = 0; i < (U32)face.mNumIndices; ++i)
|
||||
{ //copy indices, offsetting by old vertex count
|
||||
dst_idx[i] = face.mIndices[i]+offset;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
|
||||
{
|
||||
BOOL flat = mTypeMask & FLAT_MASK;
|
||||
|
||||
@@ -60,6 +60,7 @@ class LLVolumeTriangle;
|
||||
#include "llpointer.h"
|
||||
#include "llfile.h"
|
||||
#include "llalignedarray.h"
|
||||
#include "llrigginginfo.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -870,8 +871,6 @@ public:
|
||||
|
||||
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
void createTangents();
|
||||
|
||||
void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
|
||||
|
||||
void resizeVertices(S32 num_verts);
|
||||
void allocateTangents(S32 num_verts);
|
||||
@@ -961,6 +960,10 @@ public:
|
||||
|
||||
mutable BOOL mWeightsScrubbed;
|
||||
|
||||
// Which joints are rigged to, and the bounding box of any rigged
|
||||
// vertices per joint.
|
||||
LLJointRiggingInfoTab mJointRiggingInfoTab;
|
||||
|
||||
LLOctreeNode<LLVolumeTriangle>* mOctree;
|
||||
|
||||
//whether or not face has been cache optimized
|
||||
@@ -1059,7 +1062,7 @@ public:
|
||||
U32 mFaceMask; // bit array of which faces exist in this volume
|
||||
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
|
||||
|
||||
void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
|
||||
void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);
|
||||
void copyVolumeFaces(const LLVolume* volume);
|
||||
void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
|
||||
void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
|
||||
@@ -1068,7 +1071,8 @@ public:
|
||||
private:
|
||||
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
|
||||
F32 sculptGetSurfaceArea();
|
||||
void sculptGeneratePlaceholder();
|
||||
void sculptGenerateEmptyPlaceholder();
|
||||
void sculptGenerateSpherePlaceholder();
|
||||
void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);
|
||||
|
||||
|
||||
|
||||
@@ -110,9 +110,9 @@ void LLModel::optimizeVolumeFaces()
|
||||
{
|
||||
for (U32 i = 0; i < (U32)getNumVolumeFaces(); ++i)
|
||||
{
|
||||
validate_face(mVolumeFaces[i]);
|
||||
//validate_face(mVolumeFaces[i]);
|
||||
mVolumeFaces[i].optimize();
|
||||
validate_face(mVolumeFaces[i]);
|
||||
//validate_face(mVolumeFaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,11 +161,11 @@ void LLModel::sortVolumeFacesByMaterialName()
|
||||
mVolumeFaces = new_faces;
|
||||
}
|
||||
|
||||
void LLModel::trimVolumeFacesToSize(S32 new_count, LLVolume::face_list_t* remainder)
|
||||
void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remainder)
|
||||
{
|
||||
llassert(new_count <= LL_SCULPT_MESH_MAX_FACES);
|
||||
|
||||
if (new_count && (getNumVolumeFaces() > new_count))
|
||||
if (new_count && ((U32)getNumVolumeFaces() > new_count))
|
||||
{
|
||||
// Copy out remaining volume faces for alternative handling, if provided
|
||||
//
|
||||
@@ -407,40 +407,6 @@ void LLModel::setVolumeFaceData(
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size);
|
||||
}
|
||||
|
||||
void LLModel::appendFaces(LLModel *model, LLMatrix4 &transform, LLMatrix4& norm_mat)
|
||||
{
|
||||
if (mVolumeFaces.empty())
|
||||
{
|
||||
setNumVolumeFaces(1);
|
||||
}
|
||||
|
||||
LLVolumeFace& face = mVolumeFaces[mVolumeFaces.size()-1];
|
||||
|
||||
|
||||
for (S32 i = 0; i < model->getNumFaces(); ++i)
|
||||
{
|
||||
face.appendFace(model->getVolumeFace(i), transform, norm_mat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLModel::appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat)
|
||||
{
|
||||
S32 rindex = getNumVolumeFaces()-1;
|
||||
if (rindex == -1 ||
|
||||
mVolumeFaces[rindex].mNumVertices + src_face.mNumVertices >= 65536)
|
||||
{ //empty or overflow will occur, append new face
|
||||
LLVolumeFace cur_face;
|
||||
cur_face.appendFace(src_face, mat, norm_mat);
|
||||
addFace(cur_face);
|
||||
mMaterialList.push_back(src_material);
|
||||
}
|
||||
else
|
||||
{ //append to existing end face
|
||||
mVolumeFaces.rbegin()->appendFace(src_face, mat, norm_mat);
|
||||
}
|
||||
}
|
||||
|
||||
void LLModel::addFace(const LLVolumeFace& face)
|
||||
{
|
||||
if (face.mNumVertices == 0)
|
||||
@@ -523,9 +489,9 @@ void LLModel::generateNormals(F32 angle_cutoff)
|
||||
}
|
||||
|
||||
//weld vertices in temporary face, respecting angle_cutoff (step 2)
|
||||
validate_face(faceted);
|
||||
//validate_face(faceted);
|
||||
faceted.optimize(angle_cutoff);
|
||||
validate_face(faceted);
|
||||
//validate_face(faceted);
|
||||
|
||||
//generate normals for welded face based on new topology (step 3)
|
||||
|
||||
@@ -657,9 +623,9 @@ void LLModel::generateNormals(F32 angle_cutoff)
|
||||
}
|
||||
|
||||
//remove redundant vertices from new face (step 6)
|
||||
validate_face(new_face);
|
||||
//validate_face(new_face);
|
||||
new_face.optimize();
|
||||
validate_face(new_face);
|
||||
//validate_face(new_face);
|
||||
|
||||
mVolumeFaces[j] = new_face;
|
||||
}
|
||||
@@ -1043,12 +1009,14 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
||||
{ //no exact match found, get closest point
|
||||
const F32 epsilon = 1e-5f;
|
||||
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
|
||||
weight_map::iterator iter_down = ++iter_up;
|
||||
|
||||
weight_map::iterator iter_down = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
weight_map::iterator best = iter_up;
|
||||
|
||||
// iter == mSkinWeights.end()...
|
||||
F32 min_dist = (iter_up->first - pos).magVec();
|
||||
F32 min_dist = (iter->first - pos).magVec();
|
||||
|
||||
bool done = false;
|
||||
while (!done)
|
||||
@@ -1399,14 +1367,16 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
|
||||
LLMeshSkinInfo::LLMeshSkinInfo():
|
||||
mPelvisOffset(0.0),
|
||||
mLockScaleIfJointPosition(false),
|
||||
mInvalidJointsScrubbed(false)
|
||||
mInvalidJointsScrubbed(false),
|
||||
mJointNumsInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin):
|
||||
mPelvisOffset(0.0),
|
||||
mLockScaleIfJointPosition(false),
|
||||
mInvalidJointsScrubbed(false)
|
||||
mInvalidJointsScrubbed(false),
|
||||
mJointNumsInitialized(false)
|
||||
{
|
||||
fromLLSD(skin);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
float mPelvisOffset;
|
||||
bool mLockScaleIfJointPosition;
|
||||
bool mInvalidJointsScrubbed;
|
||||
bool mJointNumsInitialized;
|
||||
};
|
||||
|
||||
class LLModel : public LLVolume
|
||||
@@ -158,9 +159,6 @@ public:
|
||||
EModelStatus getStatus() const {return mStatus;}
|
||||
static std::string getStatusString(U32 status) ;
|
||||
|
||||
void appendFaces(LLModel* model, LLMatrix4& transform, LLMatrix4& normal_transform);
|
||||
void appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat);
|
||||
|
||||
void setNumVolumeFaces(S32 count);
|
||||
void setVolumeFaceData(
|
||||
S32 f,
|
||||
@@ -177,7 +175,7 @@ public:
|
||||
|
||||
void sortVolumeFacesByMaterialName();
|
||||
void normalizeVolumeFaces();
|
||||
void trimVolumeFacesToSize(S32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
|
||||
void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
|
||||
void optimizeVolumeFaces();
|
||||
void offsetMesh( const LLVector3& pivotPoint );
|
||||
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
GENERATING_VERTEX_BUFFERS,
|
||||
GENERATING_LOD,
|
||||
DONE,
|
||||
WARNING_BIND_SHAPE_ORIENTATION,
|
||||
ERROR_PARSING, //basically loading failed
|
||||
ERROR_MATERIALS,
|
||||
ERROR_PASSWORD_REQUIRED,
|
||||
|
||||
@@ -175,7 +175,7 @@ LLPrimitive::~LLPrimitive()
|
||||
{
|
||||
clearTextureList();
|
||||
// Cleanup handled by volume manager
|
||||
if (mVolumep)
|
||||
if (mVolumep && sVolumeManager)
|
||||
{
|
||||
sVolumeManager->unrefVolume(mVolumep);
|
||||
}
|
||||
@@ -586,7 +586,7 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode)
|
||||
|
||||
|
||||
// static
|
||||
// Don't crash or llerrs here! This function is used for debug strings.
|
||||
// Don't crash or LL_ERRS() here! This function is used for debug strings.
|
||||
std::string LLPrimitive::pCodeToString(const LLPCode pcode)
|
||||
{
|
||||
std::string pcode_string;
|
||||
@@ -729,6 +729,16 @@ S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac
|
||||
|
||||
BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
|
||||
{
|
||||
if (NO_LOD == detail)
|
||||
{
|
||||
// build the new object
|
||||
setChanged(GEOMETRY);
|
||||
sVolumeManager->unrefVolume(mVolumep);
|
||||
mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE);
|
||||
setNumTEs(mVolumep->getNumFaces());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLVolume *volumep;
|
||||
if (unique_volume)
|
||||
{
|
||||
@@ -1577,6 +1587,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
|
||||
return (size == 17);
|
||||
case PARAMS_LIGHT_IMAGE:
|
||||
return (size == 28);
|
||||
case PARAMS_EXTENDED_MESH:
|
||||
return (size == 4);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -2004,3 +2016,67 @@ bool LLLightImageParams::fromLLSD(LLSD& sd)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
LLExtendedMeshParams::LLExtendedMeshParams()
|
||||
{
|
||||
mType = PARAMS_EXTENDED_MESH;
|
||||
mFlags = 0;
|
||||
}
|
||||
|
||||
BOOL LLExtendedMeshParams::pack(LLDataPacker &dp) const
|
||||
{
|
||||
dp.packU32(mFlags, "flags");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLExtendedMeshParams::unpack(LLDataPacker &dp)
|
||||
{
|
||||
dp.unpackU32(mFlags, "flags");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const
|
||||
{
|
||||
if (data.mType != PARAMS_EXTENDED_MESH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data;
|
||||
if ( (param->mFlags != mFlags) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLExtendedMeshParams::copy(const LLNetworkData& data)
|
||||
{
|
||||
const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data;
|
||||
mFlags = param->mFlags;
|
||||
}
|
||||
|
||||
LLSD LLExtendedMeshParams::asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
|
||||
sd["flags"] = LLSD::Integer(mFlags);
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
|
||||
{
|
||||
if (sd.has("flags"))
|
||||
{
|
||||
setFlags( sd["flags"].asInteger());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
PARAMS_LIGHT_IMAGE = 0x40,
|
||||
PARAMS_RESERVED = 0x50, // Used on server-side
|
||||
PARAMS_MESH = 0x60,
|
||||
PARAMS_EXTENDED_MESH = 0x70,
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -288,6 +289,27 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class LLExtendedMeshParams : public LLNetworkData
|
||||
{
|
||||
protected:
|
||||
U32 mFlags;
|
||||
|
||||
public:
|
||||
static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0;
|
||||
|
||||
LLExtendedMeshParams();
|
||||
/*virtual*/ BOOL pack(LLDataPacker &dp) const;
|
||||
/*virtual*/ BOOL unpack(LLDataPacker &dp);
|
||||
/*virtual*/ bool operator==(const LLNetworkData& data) const;
|
||||
/*virtual*/ void copy(const LLNetworkData& data);
|
||||
LLSD asLLSD() const;
|
||||
operator LLSD() const { return asLLSD(); }
|
||||
bool fromLLSD(LLSD& sd);
|
||||
|
||||
void setFlags(const U32& flags) { mFlags = flags; }
|
||||
U32 getFlags() const { return mFlags; }
|
||||
|
||||
};
|
||||
|
||||
// This code is not naming-standards compliant. Leaving it like this for
|
||||
// now to make the connection to code in
|
||||
@@ -308,9 +330,9 @@ struct LLTEContents
|
||||
S16 image_rot[MAX_TES];
|
||||
U8 bump[MAX_TES];
|
||||
U8 media_flags[MAX_TES];
|
||||
U8 glow[MAX_TES];
|
||||
U8 glow[MAX_TES];
|
||||
LLMaterialID material_ids[MAX_TES];
|
||||
|
||||
|
||||
static const U32 MAX_TE_BUFFER = 4096;
|
||||
U8 packed_buffer[MAX_TE_BUFFER];
|
||||
|
||||
@@ -483,6 +505,11 @@ protected:
|
||||
U32 mMiscFlags; // home for misc bools
|
||||
|
||||
static LLVolumeMgr* sVolumeManager;
|
||||
|
||||
enum
|
||||
{
|
||||
NO_LOD = -1
|
||||
};
|
||||
};
|
||||
|
||||
inline BOOL LLPrimitive::isAvatar() const
|
||||
|
||||
@@ -1554,6 +1554,7 @@ if (WINDOWS)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
generate_viewer_version
|
||||
stage_third_party_libs
|
||||
llcommon
|
||||
${COPY_INPUT_DEPENDENCIES}
|
||||
COMMENT "Performing viewer_manifest copy"
|
||||
)
|
||||
|
||||
@@ -653,7 +653,7 @@ void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap& unit)
|
||||
{
|
||||
LLImageRaw* rawimage = gTextureList.findImage(unit.getID())->getCachedRawImage();
|
||||
|
||||
aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), rawimage->getComponents(), rawimage->getData(), 0);
|
||||
aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), rawimage->getComponents(), rawimage->getData(), 0, true);
|
||||
unit.volume_dirty = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1403,6 +1403,16 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
|
||||
}
|
||||
|
||||
//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL;
|
||||
|
||||
// Let getGeometryVolume know if a texture matrix is in play
|
||||
if (face->mTextureMatrix)
|
||||
{
|
||||
face->setState(LLFace::TEXTURE_ANIM);
|
||||
}
|
||||
else
|
||||
{
|
||||
face->clearState(LLFace::TEXTURE_ANIM);
|
||||
}
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_inv_trans, offset, true);
|
||||
|
||||
buffer->flush();
|
||||
@@ -1410,16 +1420,24 @@ void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
{
|
||||
LLVector4a* weight = vol_face.mWeights;
|
||||
if (!weight)
|
||||
LLVector4a* weights = vol_face.mWeights;
|
||||
if (!weights)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// FIXME ugly const cast
|
||||
LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
|
||||
|
||||
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
|
||||
U32 data_mask = face->getRiggedVertexBufferDataMask();
|
||||
|
||||
if (!vol_face.mWeightsScrubbed)
|
||||
{
|
||||
LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
|
||||
vol_face.mWeightsScrubbed = TRUE;
|
||||
}
|
||||
|
||||
if (buffer.isNull() ||
|
||||
buffer->getTypeMask() != data_mask ||
|
||||
@@ -1452,7 +1470,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
|
||||
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
|
||||
{
|
||||
avatar->updateSoftwareSkinnedVertices(skin, weight, vol_face, buffer);
|
||||
avatar->updateSoftwareSkinnedVertices(skin, weights, vol_face, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ BOOL LLFloaterBvhPreview::postBuild()
|
||||
// pass animation data through memory buffer
|
||||
loaderp->serialize(dp);
|
||||
dp.reset();
|
||||
success = motionp && motionp->deserialize(dp);
|
||||
success = motionp && motionp->deserialize(dp, mMotionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -411,7 +411,7 @@ BOOL LLFloaterBvhPreview::postBuild()
|
||||
motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);
|
||||
LLDataPackerBinaryBuffer dp((U8*)file_buffer, file_size);
|
||||
dp.reset();
|
||||
success = motionp && motionp->deserialize(dp);
|
||||
success = motionp && motionp->deserialize(dp, mMotionID);
|
||||
}
|
||||
|
||||
raw_animatn.close();
|
||||
|
||||
@@ -849,7 +849,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
|
||||
|
||||
if (imagep)
|
||||
{
|
||||
mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0);
|
||||
mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
|
||||
}
|
||||
|
||||
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
|
||||
|
||||
@@ -672,6 +672,11 @@ void LLFloaterModelPreview::draw()
|
||||
childSetTextArg("status", "[STATUS]", getString("status_parse_error"));
|
||||
toggleCalculateButton(false);
|
||||
}
|
||||
else
|
||||
if (mModelPreview->getLoadState() == LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION)
|
||||
{
|
||||
childSetTextArg("status", "[STATUS]", getString("status_bind_shape_orientation"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetTextArg("status", "[STATUS]", getString("status_idle"));
|
||||
@@ -1588,6 +1593,19 @@ void LLModelPreview::rebuildUploadData()
|
||||
mFMP->childDisable( "calculate_btn" );
|
||||
}
|
||||
}
|
||||
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP;
|
||||
bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean();
|
||||
if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0)
|
||||
{
|
||||
LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix);
|
||||
LLQuaternion identity;
|
||||
if (!bind_rot.isEqualEps(identity,0.01))
|
||||
{
|
||||
LL_WARNS() << "non-identity bind shape rot. mat is " << high_lod_model->mSkinInfo.mBindShapeMatrix
|
||||
<< " bind_rot " << bind_rot << LL_ENDL;
|
||||
setLoadState( LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION );
|
||||
}
|
||||
}
|
||||
}
|
||||
instance.mTransform = mat;
|
||||
mUploadData.push_back(instance);
|
||||
|
||||
@@ -37,20 +37,17 @@ void LLSkinningUtil::initClass()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLSkinningUtil::getMaxJointCount()
|
||||
{
|
||||
U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT;
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin)
|
||||
{
|
||||
return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size());
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin)
|
||||
{
|
||||
if (skin->mInvalidJointsScrubbed)
|
||||
@@ -64,8 +61,10 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
|
||||
// needed for handling of any legacy bad data.
|
||||
if (!avatar->getJoint(skin->mJointNames[j]))
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "Mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
|
||||
LL_DEBUGS("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
|
||||
skin->mJointNames[j] = "mPelvis";
|
||||
skin->mJointNumsInitialized = false; // force update after names change.
|
||||
}
|
||||
}
|
||||
skin->mInvalidJointsScrubbed = true;
|
||||
@@ -77,69 +76,43 @@ void LLSkinningUtil::initSkinningMatrixPalette(
|
||||
S32 count,
|
||||
const LLMeshSkinInfo* skin,
|
||||
LLVOAvatar *avatar,
|
||||
bool relative_to_avatar)
|
||||
bool relative_to_avatar)
|
||||
{
|
||||
for (U32 j = 0; j < (U32)count; ++j)
|
||||
{
|
||||
LLJoint *joint = NULL;
|
||||
if( skin->mJointNums[j] <= -50 )
|
||||
{
|
||||
// Give up silently.
|
||||
mat[j].loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
|
||||
continue;
|
||||
}
|
||||
else if (skin->mJointNums[j] < 0 )
|
||||
{
|
||||
joint = avatar->getJoint(skin->mJointNames[j]);
|
||||
if (!joint)
|
||||
{
|
||||
LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << " Using 'root' fallback." << LL_ENDL;
|
||||
joint = avatar->getJoint("mRoot");
|
||||
}
|
||||
if (joint)
|
||||
{
|
||||
//LL_INFOS() << "Found joint " << skin->mJointNames[j] << " Id = " << joint->getJointNum() << LL_ENDL;
|
||||
skin->mJointNums[j] = joint->getJointNum();
|
||||
}
|
||||
else
|
||||
{
|
||||
--skin->mJointNums[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
joint = avatar->getJoint(skin->mJointNums[j]);
|
||||
if (!joint)
|
||||
{
|
||||
LL_WARNS_ONCE() << "Joint not found: " << skin->mJointNames[j] << " Id = " << skin->mJointNums[j] << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (joint)
|
||||
{
|
||||
LLMatrix4a bind;
|
||||
bind.loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
|
||||
if (relative_to_avatar)
|
||||
{
|
||||
LLMatrix4a trans = joint->getWorldMatrix();
|
||||
trans.translate_affine(avatar->getPosition() * -1.f);
|
||||
mat[j].setMul(trans, bind);
|
||||
}
|
||||
else
|
||||
mat[j].setMul(joint->getWorldMatrix(), bind);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat[j].loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
|
||||
// This shouldn't happen - in mesh upload, skinned
|
||||
// rendering should be disabled unless all joints are
|
||||
// valid. In other cases of skinned rendering, invalid
|
||||
// joints should already have been removed during scrubInvalidJoints().
|
||||
LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << LL_ENDL;
|
||||
}
|
||||
}
|
||||
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
|
||||
for (U32 j = 0; j < (U32)count; ++j)
|
||||
{
|
||||
LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
|
||||
if (joint)
|
||||
{
|
||||
LLMatrix4a bind;
|
||||
bind.loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
|
||||
if (relative_to_avatar)
|
||||
{
|
||||
LLMatrix4a trans = joint->getWorldMatrix();
|
||||
trans.translate_affine(avatar->getPosition() * -1.f);
|
||||
mat[j].setMul(trans, bind);
|
||||
}
|
||||
else
|
||||
mat[j].setMul(joint->getWorldMatrix(), bind);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat[j].loadu((F32*)skin->mInvBindMatrix[j].mMatrix);
|
||||
// This shouldn't happen - in mesh upload, skinned
|
||||
// rendering should be disabled unless all joints are
|
||||
// valid. In other cases of skinned rendering, invalid
|
||||
// joints should already have been removed during scrubInvalidJoints().
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " rigged to invalid joint name " << skin->mJointNames[j]
|
||||
<< " num " << skin->mJointNums[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " avatar build state: isBuilt() " << avatar->isBuilt()
|
||||
<< " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
void LLSkinningUtil::checkSkinWeights(const LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
|
||||
{
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
@@ -179,7 +152,6 @@ void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, con
|
||||
checkSkinWeights(weights, num_vertices, skin);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSkinningUtil::getPerVertexSkinMatrix(
|
||||
const F32* weights,
|
||||
LLMatrix4a* mat,
|
||||
@@ -231,3 +203,62 @@ void LLSkinningUtil::getPerVertexSkinMatrix(
|
||||
llassert(valid_weights);
|
||||
}
|
||||
|
||||
void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar)
|
||||
{
|
||||
if (!skin->mJointNumsInitialized)
|
||||
{
|
||||
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
|
||||
{
|
||||
LLJoint *joint = NULL;
|
||||
if (skin->mJointNums[j] == -1)
|
||||
{
|
||||
joint = avatar->getJoint(skin->mJointNames[j]);
|
||||
if (joint)
|
||||
{
|
||||
skin->mJointNums[j] = joint->getJointNum();
|
||||
if (skin->mJointNums[j] < 0)
|
||||
{
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " joint has unusual number " << skin->mJointNames[j] << ": " << skin->mJointNums[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " avatar build state: isBuilt() " << avatar->isBuilt() << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " unable to find joint " << skin->mJointNames[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " avatar build state: isBuilt() " << avatar->isBuilt() << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
#if 0
|
||||
dump_avatar_and_skin_state("initJointNums joint not found", avatar, skin);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
skin->mJointNumsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This is used for extracting rotation from a bind shape matrix that
|
||||
// already has scales baked in
|
||||
LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4)
|
||||
{
|
||||
LLMatrix3 bind_mat = mat4.getMat3();
|
||||
for (auto i = 0; i < 3; i++)
|
||||
{
|
||||
F32 len = 0.0f;
|
||||
for (auto j = 0; j < 3; j++)
|
||||
{
|
||||
len += bind_mat.mMatrix[i][j] * bind_mat.mMatrix[i][j];
|
||||
}
|
||||
if (len > 0.0f)
|
||||
{
|
||||
len = sqrt(len);
|
||||
for (auto j = 0; j < 3; j++)
|
||||
{
|
||||
bind_mat.mMatrix[i][j] /= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
bind_mat.invert();
|
||||
LLQuaternion bind_rot = bind_mat.quaternion();
|
||||
bind_rot.normalize();
|
||||
return bind_rot;
|
||||
}
|
||||
|
||||
@@ -31,17 +31,18 @@ class LLVOAvatar;
|
||||
class LLMeshSkinInfo;
|
||||
class LLMatrix4a;
|
||||
|
||||
class LLSkinningUtil
|
||||
namespace LLSkinningUtil
|
||||
{
|
||||
public:
|
||||
static void initClass();
|
||||
static U32 getMaxJointCount();
|
||||
static U32 getMeshJointCount(const LLMeshSkinInfo *skin);
|
||||
static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
|
||||
static void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar, bool relative_to_avatar = false);
|
||||
static void checkSkinWeights(const LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
static void getPerVertexSkinMatrix(const F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
|
||||
void initClass();
|
||||
U32 getMaxJointCount();
|
||||
U32 getMeshJointCount(const LLMeshSkinInfo *skin);
|
||||
void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
|
||||
void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar, bool relative_to_avatar = false);
|
||||
void checkSkinWeights(const LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
void getPerVertexSkinMatrix(const F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
|
||||
void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar);
|
||||
LLQuaternion getUnscaledQuaternion(const LLMatrix4& mat4);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1193,7 +1193,7 @@ void LLVOVolume::sculpt()
|
||||
|
||||
sculpt_data = raw_image->getData();
|
||||
}
|
||||
getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
|
||||
getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());
|
||||
|
||||
//notify rebuild any other VOVolumes that reference this sculpty volume
|
||||
for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i)
|
||||
@@ -4111,6 +4111,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
||||
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar, true);
|
||||
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
|
||||
|
||||
LLVector4a av_pos;
|
||||
av_pos.load3(avatar->getPosition().mV);
|
||||
|
||||
@@ -4127,8 +4130,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
||||
continue;
|
||||
}
|
||||
LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin);
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
|
||||
|
||||
LLVector4a* pos = dst_face.mPositions;
|
||||
|
||||
@@ -4143,11 +4144,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
||||
LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
|
||||
|
||||
LLVector4a& v = vol_face.mPositions[j];
|
||||
LLVector4a t;
|
||||
LLVector4a dst;
|
||||
bind_shape_matrix.affineTransform(v, t);
|
||||
final_mat.affineTransform(t, dst);
|
||||
pos[j] = dst;
|
||||
|
||||
final_mat.mul(bind_shape_matrix);
|
||||
final_mat.affineTransform(v, pos[j]);
|
||||
|
||||
pos[j].add(av_pos);
|
||||
}
|
||||
@@ -6166,7 +6165,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
|
||||
|
||||
if (material_pass)
|
||||
{
|
||||
U32 pass[] =
|
||||
static const U32 pass[] =
|
||||
{
|
||||
LLRenderPass::PASS_MATERIAL,
|
||||
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
|
||||
|
||||
Reference in New Issue
Block a user