Merge branch 'master' of git://github.com/Shyotl/SingularityViewer into ManagedMarketplace
This commit is contained in:
@@ -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
|
||||
|
||||
159
indra/llmath/llrigginginfo.cpp
Normal file
159
indra/llmath/llrigginginfo.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @file llrigginginfo.cpp
|
||||
* @brief Functions for tracking rigged box extents
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2018, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llmath.h"
|
||||
#include "llrigginginfo.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLJointRiggingInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJointRiggingInfo::LLJointRiggingInfo()
|
||||
{
|
||||
mRiggedExtents[0].clear();
|
||||
mRiggedExtents[1].clear();
|
||||
mIsRiggedTo = false;
|
||||
}
|
||||
|
||||
bool LLJointRiggingInfo::isRiggedTo() const
|
||||
{
|
||||
return mIsRiggedTo;
|
||||
}
|
||||
|
||||
void LLJointRiggingInfo::setIsRiggedTo(bool val)
|
||||
{
|
||||
mIsRiggedTo = val;
|
||||
}
|
||||
|
||||
LLVector4a *LLJointRiggingInfo::getRiggedExtents()
|
||||
{
|
||||
return mRiggedExtents;
|
||||
}
|
||||
|
||||
const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const
|
||||
{
|
||||
return mRiggedExtents;
|
||||
}
|
||||
|
||||
// Combine two rigging info states.
|
||||
// - isRiggedTo if either of the source infos are rigged to
|
||||
// - box is union of the two sources
|
||||
void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other)
|
||||
{
|
||||
if (other.mIsRiggedTo)
|
||||
{
|
||||
if (mIsRiggedTo)
|
||||
{
|
||||
// Combine existing boxes
|
||||
update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]);
|
||||
update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize box
|
||||
mIsRiggedTo = true;
|
||||
mRiggedExtents[0] = other.mRiggedExtents[0];
|
||||
mRiggedExtents[1] = other.mRiggedExtents[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLJointRiggingInfoTab::LLJointRiggingInfoTab():
|
||||
mRigInfoPtr(NULL),
|
||||
mSize(0),
|
||||
mNeedsUpdate(true)
|
||||
{
|
||||
}
|
||||
|
||||
LLJointRiggingInfoTab::~LLJointRiggingInfoTab()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// This doesn't preserve data if the size changes. In practice
|
||||
// this doesn't matter because the size is always either
|
||||
// LL_CHARACTER_MAX_ANIMATED_JOINTS or 0.
|
||||
void LLJointRiggingInfoTab::resize(S32 size)
|
||||
{
|
||||
if (size != mSize)
|
||||
{
|
||||
clear();
|
||||
if (size > 0)
|
||||
{
|
||||
mRigInfoPtr = new LLJointRiggingInfo[size];
|
||||
mSize = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLJointRiggingInfoTab::clear()
|
||||
{
|
||||
if (mRigInfoPtr)
|
||||
{
|
||||
delete[](mRigInfoPtr);
|
||||
mRigInfoPtr = NULL;
|
||||
mSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void showDetails(const LLJointRiggingInfoTab& src, const std::string& str)
|
||||
{
|
||||
S32 count_rigged = 0;
|
||||
S32 count_box = 0;
|
||||
LLVector4a zero_vec;
|
||||
zero_vec.clear();
|
||||
for (S32 i=0; i<src.size(); i++)
|
||||
{
|
||||
if (src[i].isRiggedTo())
|
||||
{
|
||||
count_rigged++;
|
||||
if ((!src[i].getRiggedExtents()[0].equals3(zero_vec)) ||
|
||||
(!src[i].getRiggedExtents()[1].equals3(zero_vec)))
|
||||
{
|
||||
count_box++;
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("RigSpammish") << "details: " << str << " has " << count_rigged << " rigged joints, of which " << count_box << " are non-empty" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLJointRiggingInfoTab::merge(const LLJointRiggingInfoTab& src)
|
||||
{
|
||||
//showDetails(*this, "input this");
|
||||
// Size should be either LL_CHARACTER_MAX_ANIMATED_JOINTS, or 0 if
|
||||
// no data. Not necessarily the same for both inputs.
|
||||
if (src.size() > size())
|
||||
{
|
||||
resize(src.size());
|
||||
}
|
||||
S32 min_size = llmin(size(), src.size());
|
||||
for (S32 i=0; i<min_size; i++)
|
||||
{
|
||||
(*this)[i].merge(src[i]);
|
||||
}
|
||||
//showDetails(src, "input src");
|
||||
//showDetails(*this, "output this");
|
||||
|
||||
}
|
||||
100
indra/llmath/llrigginginfo.h
Normal file
100
indra/llmath/llrigginginfo.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file llrigginginfo.h
|
||||
* @brief Functions for tracking rigged box extents
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2018, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Stores information related to associated rigged mesh vertices
|
||||
// This lives in llmath because llvolume lives in llmath.
|
||||
|
||||
#ifndef LL_LLRIGGINGINFO_H
|
||||
#define LL_LLRIGGINGINFO_H
|
||||
|
||||
#include "llvector4a.h"
|
||||
|
||||
// Extents are in joint space
|
||||
// isRiggedTo is based on the state of all currently associated rigged meshes
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLJointRiggingInfo
|
||||
{
|
||||
public:
|
||||
LLJointRiggingInfo();
|
||||
bool isRiggedTo() const;
|
||||
void setIsRiggedTo(bool val);
|
||||
LLVector4a *getRiggedExtents();
|
||||
const LLVector4a *getRiggedExtents() const;
|
||||
void merge(const LLJointRiggingInfo& other);
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size)
|
||||
{
|
||||
return ll_aligned_malloc_16(size);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LL_ALIGN_16(LLVector4a mRiggedExtents[2]);
|
||||
bool mIsRiggedTo;
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
// For storing all the rigging info associated with a given avatar or
|
||||
// object, keyed by joint_num.
|
||||
// Using direct memory management instead of std::vector<> to avoid alignment issues.
|
||||
class LLJointRiggingInfoTab
|
||||
{
|
||||
public:
|
||||
LLJointRiggingInfoTab();
|
||||
~LLJointRiggingInfoTab();
|
||||
void resize(S32 size);
|
||||
void clear();
|
||||
S32 size() const { return mSize; }
|
||||
void merge(const LLJointRiggingInfoTab& src);
|
||||
LLJointRiggingInfo& operator[](S32 i) { return mRigInfoPtr[i]; }
|
||||
const LLJointRiggingInfo& operator[](S32 i) const { return mRigInfoPtr[i]; };
|
||||
bool needsUpdate() { return mNeedsUpdate; }
|
||||
void setNeedsUpdate(bool val) { mNeedsUpdate = val; }
|
||||
private:
|
||||
// Not implemented
|
||||
LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src);
|
||||
LLJointRiggingInfoTab(const LLJointRiggingInfoTab& src);
|
||||
|
||||
LLJointRiggingInfo *mRigInfoPtr;
|
||||
S32 mSize;
|
||||
bool mNeedsUpdate;
|
||||
};
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user