mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 16:15:31 +00:00
profiling
Signed-off-by: Bret Curtis <psi29a@gmail.com>
This commit is contained in:
parent
daa2761c2d
commit
26ab176389
13 changed files with 78 additions and 95 deletions
|
@ -1372,7 +1372,7 @@ namespace MWRender
|
|||
osg::Group* sheathParent = findVisitor.mFoundNode;
|
||||
if (sheathParent)
|
||||
{
|
||||
osg::Node* copy = osg::clone(nodePair.first, osg::CopyOp::DEEP_COPY_NODES);
|
||||
osg::Node* copy = static_cast<osg::Node*>(nodePair.first->clone(osg::CopyOp::DEEP_COPY_NODES));
|
||||
sheathParent->addChild(copy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,23 @@ namespace MWRender
|
|||
osg::Vec3f mViewVector;
|
||||
mutable std::vector<const osg::Node*> mNodePath;
|
||||
|
||||
void copy(const osg::Node* toCopy, osg::Group* attachTo)
|
||||
{
|
||||
const osg::Group* groupToCopy = toCopy->asGroup();
|
||||
if (toCopy->getStateSet() || toCopy->asTransform() || !groupToCopy)
|
||||
attachTo->addChild(operator()(toCopy));
|
||||
else
|
||||
{
|
||||
for (unsigned int i=0; i<groupToCopy->getNumChildren(); ++i)
|
||||
attachTo->addChild(operator()(groupToCopy->getChild(i)));
|
||||
}
|
||||
}
|
||||
|
||||
virtual osg::Node* operator() (const osg::Node* node) const
|
||||
{
|
||||
if (const osg::Drawable* d = node->asDrawable())
|
||||
return operator()(d);
|
||||
|
||||
if (dynamic_cast<const osgParticle::ParticleProcessor*>(node))
|
||||
return nullptr;
|
||||
if (dynamic_cast<const osgParticle::ParticleSystemUpdater*>(node))
|
||||
|
@ -133,12 +148,9 @@ namespace MWRender
|
|||
return n;
|
||||
}
|
||||
|
||||
if (const osg::Drawable* d = node->asDrawable())
|
||||
return operator()(d);
|
||||
|
||||
mNodePath.push_back(node);
|
||||
|
||||
osg::Node* cloned = osg::clone(node, *this);
|
||||
osg::Node* cloned = static_cast<osg::Node*>(node->clone(*this));
|
||||
cloned->setDataVariance(osg::Object::STATIC);
|
||||
cloned->setUserDataContainer(nullptr);
|
||||
cloned->setName("");
|
||||
|
@ -222,14 +234,14 @@ namespace MWRender
|
|||
|
||||
if (getCopyFlags() & DEEP_COPY_DRAWABLES)
|
||||
{
|
||||
osg::Drawable* d = osg::clone(drawable, *this);
|
||||
osg::Drawable* d = static_cast<osg::Drawable*>(drawable->clone(*this));
|
||||
d->setDataVariance(osg::Object::STATIC);
|
||||
d->setUserDataContainer(nullptr);
|
||||
d->setName("");
|
||||
return d;
|
||||
}
|
||||
else
|
||||
return osg::CopyOp::operator()(drawable);
|
||||
return const_cast<osg::Drawable*>(drawable);
|
||||
}
|
||||
virtual osg::Callback* operator() (const osg::Callback* callback) const
|
||||
{
|
||||
|
@ -388,8 +400,9 @@ namespace MWRender
|
|||
bool deleted = false;
|
||||
while(cell->getNextRef(esm[index], ref, deleted))
|
||||
{
|
||||
Misc::StringUtils::lowerCaseInPlace(ref.mRefID);
|
||||
if (std::find(cell->mMovedRefs.begin(), cell->mMovedRefs.end(), ref.mRefNum) != cell->mMovedRefs.end()) continue;
|
||||
int type = store.findStatic(Misc::StringUtils::lowerCase(ref.mRefID));
|
||||
int type = store.findStatic(ref.mRefID);
|
||||
if (!typeFilter(type,size>=2)) continue;
|
||||
if (deleted) { refs.erase(ref.mRefNum); continue; }
|
||||
refs[ref.mRefNum] = ref;
|
||||
|
@ -403,9 +416,10 @@ namespace MWRender
|
|||
for (ESM::CellRefTracker::const_iterator it = cell->mLeasedRefs.begin(); it != cell->mLeasedRefs.end(); ++it)
|
||||
{
|
||||
ESM::CellRef ref = it->first;
|
||||
Misc::StringUtils::lowerCaseInPlace(ref.mRefID);
|
||||
bool deleted = it->second;
|
||||
if (deleted) { refs.erase(ref.mRefNum); continue; }
|
||||
int type = store.findStatic(Misc::StringUtils::lowerCase(ref.mRefID));
|
||||
int type = store.findStatic(ref.mRefID);
|
||||
if (!typeFilter(type,size>=2)) continue;
|
||||
refs[ref.mRefNum] = ref;
|
||||
}
|
||||
|
@ -456,28 +470,23 @@ namespace MWRender
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string id = Misc::StringUtils::lowerCase(ref.mRefID);
|
||||
if (id == "prisonmarker" || id == "divinemarker" || id == "templemarker" || id == "northmarker")
|
||||
if (ref.mRefID == "prisonmarker" || ref.mRefID == "divinemarker" || ref.mRefID == "templemarker" || ref.mRefID == "northmarker")
|
||||
continue; // marker objects that have a hardcoded function in the game logic, should be hidden from the player
|
||||
|
||||
int type = store.findStatic(id);
|
||||
std::string model = getModel(type, id, store);
|
||||
int type = store.findStatic(ref.mRefID);
|
||||
std::string model = getModel(type, ref.mRefID, store);
|
||||
if (model.empty()) continue;
|
||||
model = "meshes/" + model;
|
||||
|
||||
bool useAnim = type != ESM::REC_STAT;
|
||||
if (useAnim)
|
||||
if (activeGrid && type != ESM::REC_STAT)
|
||||
{
|
||||
model = Misc::ResourceHelpers::correctActorModelPath(model, mSceneManager->getVFS());
|
||||
if (activeGrid)
|
||||
std::string kfname = Misc::StringUtils::lowerCase(model);
|
||||
if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0)
|
||||
{
|
||||
std::string kfname = Misc::StringUtils::lowerCase(model);
|
||||
if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0)
|
||||
{
|
||||
kfname.replace(kfname.size()-4, 4, ".kf");
|
||||
if (mSceneManager->getVFS()->exists(kfname))
|
||||
continue;
|
||||
}
|
||||
kfname.replace(kfname.size()-4, 4, ".kf");
|
||||
if (mSceneManager->getVFS()->exists(kfname))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,6 +530,7 @@ namespace MWRender
|
|||
osg::ref_ptr<osg::Group> mergeGroup = new osg::Group;
|
||||
osg::ref_ptr<TemplateRef> templateRefs = new TemplateRef;
|
||||
osgUtil::StateToCompile stateToCompile(0, nullptr);
|
||||
CopyOp copyop;
|
||||
for (const auto& pair : nodes)
|
||||
{
|
||||
const osg::Node* cnode = pair.first;
|
||||
|
@ -555,35 +565,29 @@ namespace MWRender
|
|||
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(matrix);
|
||||
trans->setDataVariance(osg::Object::STATIC);
|
||||
|
||||
CopyOp co;
|
||||
co.setCopyFlags(merge ? osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES : osg::CopyOp::DEEP_COPY_NODES);
|
||||
co.mOptimizeBillboards = (size > 1/4.f);
|
||||
co.mNodePath.push_back(trans);
|
||||
co.mSqrDistance = (viewPoint - pos).length2();
|
||||
co.mViewVector = (viewPoint - worldCenter);
|
||||
osg::ref_ptr<osg::Node> node = osg::clone(cnode, co);
|
||||
node->setUserDataContainer(nullptr);
|
||||
copyop.setCopyFlags(merge ? osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES : osg::CopyOp::DEEP_COPY_NODES);
|
||||
copyop.mOptimizeBillboards = (size > 1/4.f);
|
||||
copyop.mNodePath.push_back(trans);
|
||||
copyop.mSqrDistance = (viewPoint - pos).length2();
|
||||
copyop.mViewVector = (viewPoint - worldCenter);
|
||||
copyop.copy(cnode, trans);
|
||||
|
||||
if (activeGrid)
|
||||
{
|
||||
if (merge)
|
||||
{
|
||||
AddRefnumMarkerVisitor visitor(ref.mRefNum);
|
||||
node->accept(visitor);
|
||||
trans->accept(visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<RefnumMarker> marker = new RefnumMarker; marker->mRefnum = ref.mRefNum;
|
||||
node->getOrCreateUserDataContainer()->addUserObject(marker);
|
||||
trans->getOrCreateUserDataContainer()->addUserObject(marker);
|
||||
}
|
||||
}
|
||||
|
||||
trans->addChild(node);
|
||||
|
||||
if (merge)
|
||||
mergeGroup->addChild(trans);
|
||||
else
|
||||
group->addChild(trans);
|
||||
osg::Group* attachTo = merge ? mergeGroup : group;
|
||||
attachTo->addChild(trans);
|
||||
++numinstances;
|
||||
}
|
||||
if (numinstances > 0)
|
||||
|
|
|
@ -139,15 +139,12 @@ namespace MWWorld
|
|||
std::string idLower = Misc::StringUtils::lowerCase(id);
|
||||
|
||||
typename Dynamic::const_iterator dit = mDynamic.find(idLower);
|
||||
if (dit != mDynamic.end()) {
|
||||
if (dit != mDynamic.end())
|
||||
return &dit->second;
|
||||
}
|
||||
|
||||
typename std::map<std::string, T>::const_iterator it = mStatic.find(idLower);
|
||||
|
||||
if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->second.mId, id)) {
|
||||
if (it != mStatic.end())
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -156,10 +153,8 @@ namespace MWWorld
|
|||
{
|
||||
std::string idLower = Misc::StringUtils::lowerCase(id);
|
||||
typename std::map<std::string, T>::const_iterator it = mStatic.find(idLower);
|
||||
|
||||
if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->second.mId, id)) {
|
||||
if (it != mStatic.end())
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -289,7 +284,7 @@ namespace MWWorld
|
|||
|
||||
typename std::map<std::string, T>::iterator it = mStatic.find(idLower);
|
||||
|
||||
if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->second.mId, id)) {
|
||||
if (it != mStatic.end()) {
|
||||
// delete from the static part of mShared
|
||||
typename std::vector<T *>::iterator sharedIter = mShared.begin();
|
||||
typename std::vector<T *>::iterator end = sharedIter + mStatic.size();
|
||||
|
@ -566,7 +561,7 @@ namespace MWWorld
|
|||
|
||||
std::map<std::string, ESM::Cell>::const_iterator it = mInt.find(cell.mName);
|
||||
|
||||
if (it != mInt.end() && Misc::StringUtils::ciEqual(it->second.mName, id)) {
|
||||
if (it != mInt.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
|
@ -1129,9 +1124,8 @@ namespace MWWorld
|
|||
{
|
||||
auto it = mStatic.find(Misc::StringUtils::lowerCase(id));
|
||||
|
||||
if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->second.mId, id)) {
|
||||
if (it != mStatic.end())
|
||||
mStatic.erase(it);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -232,19 +232,3 @@ void ESM::CellRef::blank()
|
|||
mPos.rot[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ESM::operator== (const RefNum& left, const RefNum& right)
|
||||
{
|
||||
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
|
||||
}
|
||||
|
||||
bool ESM::operator< (const RefNum& left, const RefNum& right)
|
||||
{
|
||||
if (left.mIndex<right.mIndex)
|
||||
return true;
|
||||
|
||||
if (left.mIndex>right.mIndex)
|
||||
return false;
|
||||
|
||||
return left.mContentFile<right.mContentFile;
|
||||
}
|
||||
|
|
|
@ -114,8 +114,20 @@ namespace ESM
|
|||
void blank();
|
||||
};
|
||||
|
||||
bool operator== (const RefNum& left, const RefNum& right);
|
||||
bool operator< (const RefNum& left, const RefNum& right);
|
||||
inline bool operator== (const RefNum& left, const RefNum& right)
|
||||
{
|
||||
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
|
||||
}
|
||||
|
||||
inline bool operator< (const RefNum& left, const RefNum& right)
|
||||
{
|
||||
if (left.mIndex<right.mIndex)
|
||||
return true;
|
||||
if (left.mIndex>right.mIndex)
|
||||
return false;
|
||||
return left.mContentFile<right.mContentFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -372,7 +372,7 @@ AlphaController::AlphaController(const AlphaController ©, const osg::CopyOp
|
|||
|
||||
void AlphaController::setDefaults(osg::StateSet *stateset)
|
||||
{
|
||||
stateset->setAttribute(osg::clone(mBaseMaterial.get(), osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
|
||||
stateset->setAttribute(static_cast<osg::Material*>(mBaseMaterial->clone(osg::CopyOp::DEEP_COPY_ALL)), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)
|
||||
|
@ -408,7 +408,7 @@ MaterialColorController::MaterialColorController(const MaterialColorController &
|
|||
|
||||
void MaterialColorController::setDefaults(osg::StateSet *stateset)
|
||||
{
|
||||
stateset->setAttribute(osg::clone(mBaseMaterial.get(), osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
|
||||
stateset->setAttribute(static_cast<osg::Material*>(mBaseMaterial->clone(osg::CopyOp::DEEP_COPY_ALL)), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
void MaterialColorController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)
|
||||
|
|
|
@ -277,7 +277,7 @@ Emitter::Emitter(const Emitter ©, const osg::CopyOp ©op)
|
|||
, mPlacer(copy.mPlacer)
|
||||
, mShooter(copy.mShooter)
|
||||
// need a deep copy because the remainder is stored in the object
|
||||
, mCounter(osg::clone(copy.mCounter.get(), osg::CopyOp::DEEP_COPY_ALL))
|
||||
, mCounter(static_cast<osgParticle::Counter*>(copy.mCounter->clone(osg::CopyOp::DEEP_COPY_ALL)))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -577,7 +577,7 @@ namespace Resource
|
|||
|
||||
osg::ref_ptr<osg::Node> SceneManager::createInstance(const osg::Node *base)
|
||||
{
|
||||
osg::ref_ptr<osg::Node> cloned = osg::clone(base, SceneUtil::CopyOp());
|
||||
osg::ref_ptr<osg::Node> cloned = static_cast<osg::Node*>(base->clone(SceneUtil::CopyOp()));
|
||||
|
||||
// add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache
|
||||
cloned->getOrCreateUserDataContainer()->addUserObject(new TemplateRef(base));
|
||||
|
|
|
@ -22,20 +22,11 @@ namespace SceneUtil
|
|||
| osg::CopyOp::DEEP_COPY_USERDATA);
|
||||
}
|
||||
|
||||
osg::StateSet* CopyOp::operator ()(const osg::StateSet* stateset) const
|
||||
{
|
||||
if (!stateset)
|
||||
return nullptr;
|
||||
if (stateset->getDataVariance() == osg::StateSet::DYNAMIC)
|
||||
return osg::clone(stateset, *this);
|
||||
return const_cast<osg::StateSet*>(stateset);
|
||||
}
|
||||
|
||||
osg::Object* CopyOp::operator ()(const osg::Object* node) const
|
||||
{
|
||||
// We should copy node transformations when we copy node
|
||||
if (const NifOsg::NodeUserData* data = dynamic_cast<const NifOsg::NodeUserData*>(node))
|
||||
return osg::clone(data, *this);
|
||||
if (dynamic_cast<const NifOsg::NodeUserData*>(node))
|
||||
return static_cast<NifOsg::NodeUserData*>(node->clone(*this));
|
||||
|
||||
return osg::CopyOp::operator()(node);
|
||||
}
|
||||
|
@ -60,7 +51,7 @@ namespace SceneUtil
|
|||
|
||||
if (dynamic_cast<const SceneUtil::RigGeometry*>(drawable) || dynamic_cast<const SceneUtil::MorphGeometry*>(drawable))
|
||||
{
|
||||
return osg::clone(drawable, *this);
|
||||
return static_cast<osg::Drawable*>(drawable->clone(*this));
|
||||
}
|
||||
|
||||
return osg::CopyOp::operator()(drawable);
|
||||
|
@ -68,7 +59,7 @@ namespace SceneUtil
|
|||
|
||||
osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const
|
||||
{
|
||||
osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::DEEP_COPY_CALLBACKS);
|
||||
osgParticle::ParticleProcessor* cloned = static_cast<osgParticle::ParticleProcessor*>(processor->clone(osg::CopyOp::DEEP_COPY_CALLBACKS));
|
||||
for (const auto& oldPsNewPsPair : mOldPsToNewPs)
|
||||
{
|
||||
if (processor->getParticleSystem() == oldPsNewPsPair.first)
|
||||
|
@ -84,7 +75,7 @@ namespace SceneUtil
|
|||
|
||||
osgParticle::ParticleSystem* CopyOp::operator ()(const osgParticle::ParticleSystem* partsys) const
|
||||
{
|
||||
osgParticle::ParticleSystem* cloned = osg::clone(partsys, *this);
|
||||
osgParticle::ParticleSystem* cloned = static_cast<osgParticle::ParticleSystem*>(partsys->clone(*this));
|
||||
|
||||
for (const auto& processorPsPair : mProcessorToOldPs)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,6 @@ namespace SceneUtil
|
|||
|
||||
/// @par Defines the cloning behaviour we need:
|
||||
/// * Assigns updated ParticleSystem pointers on cloned emitters and programs.
|
||||
/// * Creates deep copy of StateSets if they have a DYNAMIC data variance.
|
||||
/// * Deep copies RigGeometry and MorphGeometry so they can animate without affecting clones.
|
||||
/// @warning Do not use an object of this class for more than one copy operation.
|
||||
class CopyOp : public osg::CopyOp
|
||||
|
@ -31,7 +30,6 @@ namespace SceneUtil
|
|||
virtual osg::Node* operator() (const osg::Node* node) const;
|
||||
virtual osg::Drawable* operator() (const osg::Drawable* drawable) const;
|
||||
|
||||
virtual osg::StateSet* operator() (const osg::StateSet* stateset) const;
|
||||
virtual osg::Object* operator ()(const osg::Object* node) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -44,7 +44,7 @@ void MorphGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeom)
|
|||
osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject);
|
||||
vbo->setUsage(GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
osg::ref_ptr<osg::Array> vertexArray = osg::clone(from.getVertexArray(), osg::CopyOp::DEEP_COPY_ALL);
|
||||
osg::ref_ptr<osg::Array> vertexArray = static_cast<osg::Array*>(from.getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
if (vertexArray)
|
||||
{
|
||||
vertexArray->setVertexBufferObject(vbo);
|
||||
|
|
|
@ -600,7 +600,7 @@ bool needvbo(const osg::Geometry* geom)
|
|||
|
||||
osg::Array* cloneArray(osg::Array* array, osg::VertexBufferObject*& vbo, const osg::Geometry* geom)
|
||||
{
|
||||
array = osg::clone(array, osg::CopyOp::DEEP_COPY_ALL);
|
||||
array = static_cast<osg::Array*>(array->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
if (!vbo && needvbo(geom))
|
||||
vbo = new osg::VertexBufferObject;
|
||||
if (vbo)
|
||||
|
@ -1135,7 +1135,7 @@ osg::PrimitiveSet* clonePrimitive(osg::PrimitiveSet* ps, osg::ElementBufferObjec
|
|||
{
|
||||
if (ps->referenceCount() <= 1)
|
||||
return ps;
|
||||
ps = osg::clone(ps, osg::CopyOp::DEEP_COPY_ALL);
|
||||
ps = static_cast<osg::PrimitiveSet*>(ps->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
|
||||
osg::DrawElements* drawElements = ps->getDrawElements();
|
||||
if (!drawElements) return ps;
|
||||
|
|
|
@ -77,7 +77,7 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
|
|||
osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject);
|
||||
vbo->setUsage(GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
osg::ref_ptr<osg::Array> vertexArray = osg::clone(from.getVertexArray(), osg::CopyOp::DEEP_COPY_ALL);
|
||||
osg::ref_ptr<osg::Array> vertexArray = static_cast<osg::Array*>(from.getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
if (vertexArray)
|
||||
{
|
||||
vertexArray->setVertexBufferObject(vbo);
|
||||
|
@ -86,7 +86,7 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
|
|||
|
||||
if (const osg::Array* normals = from.getNormalArray())
|
||||
{
|
||||
osg::ref_ptr<osg::Array> normalArray = osg::clone(normals, osg::CopyOp::DEEP_COPY_ALL);
|
||||
osg::ref_ptr<osg::Array> normalArray = static_cast<osg::Array*>(normals->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
if (normalArray)
|
||||
{
|
||||
normalArray->setVertexBufferObject(vbo);
|
||||
|
@ -97,7 +97,7 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
|
|||
if (const osg::Vec4Array* tangents = dynamic_cast<const osg::Vec4Array*>(from.getTexCoordArray(7)))
|
||||
{
|
||||
mSourceTangents = tangents;
|
||||
osg::ref_ptr<osg::Array> tangentArray = osg::clone(tangents, osg::CopyOp::DEEP_COPY_ALL);
|
||||
osg::ref_ptr<osg::Array> tangentArray = static_cast<osg::Array*>(tangents->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
tangentArray->setVertexBufferObject(vbo);
|
||||
to.setTexCoordArray(7, tangentArray, osg::Array::BIND_PER_VERTEX);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue