A few more rigging related things added in. Also fixed vertex weights
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
LLStringTable LLCharacter::sVisualParamNames(1024);
|
||||
|
||||
std::vector< LLCharacter* > LLCharacter::sInstances;
|
||||
|
||||
BOOL LLCharacter::sAllowInstancesChange = TRUE ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLCharacter()
|
||||
@@ -59,8 +59,10 @@ LLCharacter::LLCharacter()
|
||||
mSkeletonSerialNum( 0 ),
|
||||
mInAppearance( false )
|
||||
{
|
||||
mMotionController.setCharacter( this );
|
||||
llassert_always(sAllowInstancesChange) ;
|
||||
sInstances.push_back(this);
|
||||
|
||||
mMotionController.setCharacter( this );
|
||||
mPauseRequest = new LLPauseRequestHandle();
|
||||
}
|
||||
|
||||
@@ -77,11 +79,22 @@ LLCharacter::~LLCharacter()
|
||||
{
|
||||
delete param;
|
||||
}
|
||||
std::vector<LLCharacter*>::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
|
||||
if (iter != sInstances.end())
|
||||
|
||||
U32 i ;
|
||||
U32 size = sInstances.size() ;
|
||||
for(i = 0 ; i < size ; i++)
|
||||
{
|
||||
sInstances.erase(iter);
|
||||
if(sInstances[i] == this)
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
llassert_always(i < size) ;
|
||||
|
||||
llassert_always(sAllowInstancesChange) ;
|
||||
sInstances[i] = sInstances[size - 1] ;
|
||||
sInstances.pop_back() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -279,6 +279,7 @@ public:
|
||||
void setSkeletonSerialNum( U32 num ) { mSkeletonSerialNum = num; }
|
||||
|
||||
static std::vector< LLCharacter* > sInstances;
|
||||
static BOOL sAllowInstancesChange ; //debug use
|
||||
|
||||
protected:
|
||||
LLMotionController mMotionController;
|
||||
|
||||
@@ -1173,37 +1173,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
if (!tep) rebuild_color = FALSE; // can't get color when tep is NULL
|
||||
U8 bump_code = tep ? tep->getBumpmap() : 0;
|
||||
|
||||
if (rebuild_pos)
|
||||
{
|
||||
mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
|
||||
}
|
||||
if (rebuild_normal)
|
||||
{
|
||||
mVertexBuffer->getNormalStrider(normals, mGeomIndex);
|
||||
}
|
||||
if (rebuild_binormal)
|
||||
{
|
||||
mVertexBuffer->getBinormalStrider(binormals, mGeomIndex);
|
||||
}
|
||||
#if MESH_ENABLED
|
||||
if (rebuild_weights)
|
||||
{
|
||||
mVertexBuffer->getWeight4Strider(weights, mGeomIndex);
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
if (rebuild_tcoord)
|
||||
{
|
||||
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex);
|
||||
if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
|
||||
{
|
||||
mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex);
|
||||
}
|
||||
}
|
||||
if (rebuild_color)
|
||||
{
|
||||
mVertexBuffer->getColorStrider(colors, mGeomIndex);
|
||||
}
|
||||
|
||||
|
||||
BOOL is_static = mDrawablep->isStatic();
|
||||
@@ -1249,6 +1218,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
{
|
||||
indicesp[i] = vf.mIndices[i] + index_offset;
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
|
||||
LLMatrix4a mat_normal;
|
||||
@@ -1394,6 +1365,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (!do_bump)
|
||||
{ //not in atlas or not bump mapped, might be able to do a cheap update
|
||||
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex);
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
|
||||
{
|
||||
if (!do_tex_mat)
|
||||
@@ -1467,9 +1440,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
else
|
||||
{ //either bump mapped or in atlas, just do the whole expensive loop
|
||||
mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex);
|
||||
|
||||
std::vector<LLVector2> bump_tc;
|
||||
|
||||
@@ -1523,9 +1499,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
|
||||
|
||||
if (do_bump)
|
||||
{
|
||||
mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex);
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
@@ -1553,13 +1532,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
|
||||
|
||||
*tex_coords2++ = tc;
|
||||
}
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rebuild_pos)
|
||||
{
|
||||
mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
|
||||
LLMatrix4a mat_vert;
|
||||
mat_vert.loadu(mat_vert_in);
|
||||
|
||||
@@ -1572,10 +1554,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
|
||||
if (rebuild_normal)
|
||||
{
|
||||
mVertexBuffer->getNormalStrider(normals, mGeomIndex);
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a normal;
|
||||
@@ -1583,10 +1567,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
normal.normalize3fast();
|
||||
normals[i].set(normal.getF32ptr());
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
|
||||
if (rebuild_binormal)
|
||||
{
|
||||
mVertexBuffer->getBinormalStrider(binormals, mGeomIndex);
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a binormal;
|
||||
@@ -1594,24 +1581,31 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
binormal.normalize3fast();
|
||||
binormals[i].set(binormal.getF32ptr());
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
|
||||
#if MESH_ENABLED
|
||||
if (rebuild_weights && vf.mWeights)
|
||||
{
|
||||
mVertexBuffer->getWeight4Strider(weights, mGeomIndex);
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
weights[i].set(*(weights.get()));
|
||||
weights[i].set(vf.mWeights[i].getF32ptr());
|
||||
}
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
if (rebuild_color)
|
||||
{
|
||||
mVertexBuffer->getColorStrider(colors, mGeomIndex);
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
colors[i] = color;
|
||||
}
|
||||
|
||||
//mVertexBuffer->setBuffer(0);
|
||||
}
|
||||
|
||||
if (rebuild_tcoord)
|
||||
|
||||
@@ -38,13 +38,18 @@
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llvolume.h"
|
||||
#include "llvolumeoctree.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llface.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llagent.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llcamera.h"
|
||||
#include "pipeline.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llmeshrepository.h"
|
||||
#endif //MESH_ENABLED
|
||||
#include "llrender.h"
|
||||
#include "lloctree.h"
|
||||
#include "llvoavatar.h"
|
||||
@@ -3467,7 +3472,31 @@ public:
|
||||
if (vobj)
|
||||
{
|
||||
LLVector3 intersection;
|
||||
if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
|
||||
bool skip_check = false;
|
||||
#if MESH_ENABLED
|
||||
if (vobj->isAvatar())
|
||||
{
|
||||
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
|
||||
if (avatar->isSelf() && gFloaterTools->getVisible())
|
||||
{
|
||||
LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal);
|
||||
if (hit)
|
||||
{
|
||||
mEnd = intersection;
|
||||
if (mIntersection)
|
||||
{
|
||||
*mIntersection = intersection;
|
||||
}
|
||||
|
||||
mHit = hit->mDrawable;
|
||||
skip_check = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
|
||||
{
|
||||
mEnd = intersection; // shorten ray so we only find CLOSER hits
|
||||
if (mIntersection)
|
||||
|
||||
@@ -1753,6 +1753,33 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#if MESH_ENABLED
|
||||
if (isSelf())
|
||||
{
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
iter != mAttachmentPoints.end();
|
||||
++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject* attached_object = (*attachment_iter);
|
||||
|
||||
if (attached_object && !attached_object->isDead() && attachment->getValid())
|
||||
{
|
||||
LLDrawable* drawable = attached_object->mDrawable;
|
||||
if (drawable->isState(LLDrawable::RIGGED))
|
||||
{ //regenerate octree for rigged attachment
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
}
|
||||
|
||||
LLVector3 position;
|
||||
@@ -1769,6 +1796,58 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if MESH_ENABLED
|
||||
LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
|
||||
S32 face,
|
||||
BOOL pick_transparent,
|
||||
S32* face_hit,
|
||||
LLVector3* intersection,
|
||||
LLVector2* tex_coord,
|
||||
LLVector3* normal,
|
||||
LLVector3* bi_normal)
|
||||
{
|
||||
if (isSelf() && !gAgent.needsRenderAvatar())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLViewerObject* hit = NULL;
|
||||
|
||||
if (lineSegmentBoundingBox(start, end))
|
||||
{
|
||||
LLVector3 local_end = end;
|
||||
LLVector3 local_intersection;
|
||||
|
||||
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
iter != mAttachmentPoints.end();
|
||||
++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject* attached_object = (*attachment_iter);
|
||||
|
||||
if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal))
|
||||
{
|
||||
local_end = local_intersection;
|
||||
if (intersection)
|
||||
{
|
||||
*intersection = local_intersection;
|
||||
}
|
||||
|
||||
hit = attached_object;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parseSkeletonFile()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -7247,6 +7326,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
|
||||
if (attachment->isObjectAttached(viewer_object))
|
||||
{
|
||||
LLCOFMgr::instance().addAttachment(viewer_object->getAttachmentItemID());
|
||||
updateLODRiggedAttachments();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10731,16 +10811,19 @@ U32 LLVOAvatar::getPartitionType() const
|
||||
//static
|
||||
void LLVOAvatar::updateImpostors()
|
||||
{
|
||||
LLCharacter::sAllowInstancesChange = FALSE ;
|
||||
|
||||
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
|
||||
iter != LLCharacter::sInstances.end(); ++iter)
|
||||
iter != LLCharacter::sInstances.end(); ++iter)
|
||||
{
|
||||
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
|
||||
|
||||
if (!avatar->isDead() && avatar->needsImpostorUpdate() && avatar->isVisible() && avatar->isImpostor())
|
||||
{
|
||||
gPipeline.generateImpostor(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
LLCharacter::sAllowInstancesChange = TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLVOAvatar::isImpostor() const
|
||||
|
||||
@@ -148,7 +148,17 @@ public:
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
|
||||
#if MESH_ENABLED
|
||||
LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
BOOL pick_transparent = FALSE,
|
||||
S32* face_hit = NULL, // which face was hit
|
||||
LLVector3* intersection = NULL, // return the intersection point
|
||||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector3* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
|
||||
|
||||
#endif //MESH_ENABLED
|
||||
//--------------------------------------------------------------------
|
||||
// LLCharacter interface and related
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@@ -811,7 +811,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
||||
|
||||
if (mVolumeImpl)
|
||||
{
|
||||
mVolumeImpl->onSetVolume(volume_params, detail); //mLOD ?
|
||||
mVolumeImpl->onSetVolume(volume_params, mLOD); //detail ?
|
||||
}
|
||||
|
||||
updateSculptTexture();
|
||||
|
||||
Reference in New Issue
Block a user