mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 04:39:51 +02:00
Merge pull request #4490 from ZappoMan/avatarClipBugs
Bug Fix - hack to get avatar parts rendering, fix to crash in updateJointState
This commit is contained in:
commit
f54d5612a6
3 changed files with 104 additions and 24 deletions
|
@ -87,7 +87,8 @@ void FaceModel::maybeUpdateEyeRotation(Model* model, const JointState& parentSta
|
||||||
void FaceModel::updateJointState(int index) {
|
void FaceModel::updateJointState(int index) {
|
||||||
JointState& state = _jointStates[index];
|
JointState& state = _jointStates[index];
|
||||||
const FBXJoint& joint = state.getFBXJoint();
|
const FBXJoint& joint = state.getFBXJoint();
|
||||||
if (joint.parentIndex != -1) {
|
// guard against out-of-bounds access to _jointStates
|
||||||
|
if (joint.parentIndex != -1 && joint.parentIndex >= 0 && joint.parentIndex < _jointStates.size()) {
|
||||||
const JointState& parentState = _jointStates.at(joint.parentIndex);
|
const JointState& parentState = _jointStates.at(joint.parentIndex);
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
if (index == geometry.neckJointIndex) {
|
if (index == geometry.neckJointIndex) {
|
||||||
|
|
|
@ -727,19 +727,19 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
|
|
||||||
//renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, book isSkinned, args);
|
//renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, book isSkinned, args);
|
||||||
int opaqueMeshPartsRendered = 0;
|
int opaqueMeshPartsRendered = 0;
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args, true);
|
||||||
|
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args, true);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args, true);
|
||||||
|
|
||||||
// render translucent meshes afterwards
|
// render translucent meshes afterwards
|
||||||
//DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(false, true, true);
|
//DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(false, true, true);
|
||||||
|
@ -842,10 +842,67 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
args->_translucentMeshPartsRendered = translucentMeshPartsRendered;
|
args->_translucentMeshPartsRendered = translucentMeshPartsRendered;
|
||||||
args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered;
|
args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WANT_DEBUG_MESHBOXES
|
||||||
|
renderDebugMeshBoxes();
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::renderDebugMeshBoxes() {
|
||||||
|
int colorNdx = 0;
|
||||||
|
foreach(AABox box, _calculatedMeshBoxes) {
|
||||||
|
if (_debugMeshBoxesID == GeometryCache::UNKNOWN_ID) {
|
||||||
|
_debugMeshBoxesID = DependencyManager::get<GeometryCache>()->allocateID();
|
||||||
|
}
|
||||||
|
QVector<glm::vec3> points;
|
||||||
|
|
||||||
|
glm::vec3 brn = box.getCorner();
|
||||||
|
glm::vec3 bln = brn + glm::vec3(box.getDimensions().x, 0, 0);
|
||||||
|
glm::vec3 brf = brn + glm::vec3(0, 0, box.getDimensions().z);
|
||||||
|
glm::vec3 blf = brn + glm::vec3(box.getDimensions().x, 0, box.getDimensions().z);
|
||||||
|
|
||||||
|
glm::vec3 trn = brn + glm::vec3(0, box.getDimensions().y, 0);
|
||||||
|
glm::vec3 tln = bln + glm::vec3(0, box.getDimensions().y, 0);
|
||||||
|
glm::vec3 trf = brf + glm::vec3(0, box.getDimensions().y, 0);
|
||||||
|
glm::vec3 tlf = blf + glm::vec3(0, box.getDimensions().y, 0);
|
||||||
|
|
||||||
|
points << brn << bln;
|
||||||
|
points << brf << blf;
|
||||||
|
points << brn << brf;
|
||||||
|
points << bln << blf;
|
||||||
|
|
||||||
|
points << trn << tln;
|
||||||
|
points << trf << tlf;
|
||||||
|
points << trn << trf;
|
||||||
|
points << tln << tlf;
|
||||||
|
|
||||||
|
points << brn << trn;
|
||||||
|
points << brf << trf;
|
||||||
|
points << bln << tln;
|
||||||
|
points << blf << tlf;
|
||||||
|
|
||||||
|
glm::vec4 color[] = {
|
||||||
|
{ 1.0f, 0.0f, 0.0f, 1.0f }, // red
|
||||||
|
{ 0.0f, 1.0f, 0.0f, 1.0f }, // green
|
||||||
|
{ 0.0f, 0.0f, 1.0f, 1.0f }, // blue
|
||||||
|
{ 1.0f, 0.0f, 1.0f, 1.0f }, // purple
|
||||||
|
{ 1.0f, 1.0f, 0.0f, 1.0f }, // yellow
|
||||||
|
{ 0.0f, 1.0f, 1.0f, 1.0f }, // cyan
|
||||||
|
{ 1.0f, 1.0f, 1.0f, 1.0f }, // white
|
||||||
|
{ 0.0f, 0.5f, 0.0f, 1.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.5f, 1.0f },
|
||||||
|
{ 0.5f, 0.0f, 0.5f, 1.0f },
|
||||||
|
{ 0.5f, 0.5f, 0.0f, 1.0f },
|
||||||
|
{ 0.0f, 0.5f, 0.5f, 1.0f } };
|
||||||
|
|
||||||
|
DependencyManager::get<GeometryCache>()->updateVertices(_debugMeshBoxesID, points, color[colorNdx]);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderVertices(gpu::LINES, _debugMeshBoxesID);
|
||||||
|
colorNdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Extents Model::getBindExtents() const {
|
Extents Model::getBindExtents() const {
|
||||||
if (!isActive()) {
|
if (!isActive()) {
|
||||||
return Extents();
|
return Extents();
|
||||||
|
@ -1306,8 +1363,11 @@ void Model::updateJointState(int index) {
|
||||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
state.computeTransform(parentTransform);
|
state.computeTransform(parentTransform);
|
||||||
} else {
|
} else {
|
||||||
const JointState& parentState = _jointStates.at(parentIndex);
|
// guard against out-of-bounds access to _jointStates
|
||||||
state.computeTransform(parentState.getTransform(), parentState.getTransformChanged());
|
if (joint.parentIndex >= 0 && joint.parentIndex < _jointStates.size()) {
|
||||||
|
const JointState& parentState = _jointStates.at(parentIndex);
|
||||||
|
state.computeTransform(parentState.getTransform(), parentState.getTransformChanged());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2299,7 +2359,8 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||||
|
bool forceRenderSomeMeshes) {
|
||||||
|
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
int meshPartsRendered = 0;
|
int meshPartsRendered = 0;
|
||||||
|
@ -2319,8 +2380,10 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
||||||
|
|
||||||
Locations* locations;
|
Locations* locations;
|
||||||
SkinLocations* skinLocations;
|
SkinLocations* skinLocations;
|
||||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
|
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
|
args, locations, skinLocations);
|
||||||
|
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||||
|
args, locations, skinLocations, forceRenderSomeMeshes);
|
||||||
GLBATCH(glUseProgram)(0);
|
GLBATCH(glUseProgram)(0);
|
||||||
|
|
||||||
return meshPartsRendered;
|
return meshPartsRendered;
|
||||||
|
@ -2328,7 +2391,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
||||||
|
|
||||||
|
|
||||||
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
|
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
|
||||||
Locations* locations, SkinLocations* skinLocations) {
|
Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
@ -2364,11 +2427,21 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
||||||
// if we got here, then check to see if this mesh is in view
|
// if we got here, then check to see if this mesh is in view
|
||||||
if (args) {
|
if (args) {
|
||||||
bool shouldRender = true;
|
bool shouldRender = true;
|
||||||
|
bool forceRender = false;
|
||||||
args->_meshesConsidered++;
|
args->_meshesConsidered++;
|
||||||
|
|
||||||
if (args->_viewFrustum) {
|
if (args->_viewFrustum) {
|
||||||
shouldRender = args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
|
|
||||||
if (shouldRender) {
|
// NOTE: This is a hack to address the fact that for avatar meshes, the _calculatedMeshBoxes can be wrong
|
||||||
|
// for some meshes. Those meshes where the mesh's modelTransform is the identity matrix, and will have
|
||||||
|
// incorrectly calculated mesh boxes. In this case, we will ignore the box and assume it's visible.
|
||||||
|
if (forceRenderSomeMeshes && (geometry.meshes.at(i).modelTransform == glm::mat4())) {
|
||||||
|
forceRender = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldRender = forceRender || args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
|
||||||
|
|
||||||
|
if (shouldRender && !forceRender) {
|
||||||
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
|
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
|
||||||
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
|
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
|
||||||
distance);
|
distance);
|
||||||
|
|
|
@ -444,6 +444,9 @@ private:
|
||||||
QVector<int> _meshesOpaqueLightmapTangentsSpecular;
|
QVector<int> _meshesOpaqueLightmapTangentsSpecular;
|
||||||
QVector<int> _meshesOpaqueLightmapSpecular;
|
QVector<int> _meshesOpaqueLightmapSpecular;
|
||||||
|
|
||||||
|
// debug rendering support
|
||||||
|
void renderDebugMeshBoxes();
|
||||||
|
int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID;
|
||||||
|
|
||||||
// Scene rendering support
|
// Scene rendering support
|
||||||
static QVector<Model*> _modelsInScene;
|
static QVector<Model*> _modelsInScene;
|
||||||
|
@ -456,12 +459,15 @@ private:
|
||||||
void renderSetup(RenderArgs* args);
|
void renderSetup(RenderArgs* args);
|
||||||
bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
|
bool renderCore(float alpha, RenderMode mode, RenderArgs* args);
|
||||||
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL);
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
||||||
|
bool forceRenderSomeMeshes = false);
|
||||||
|
|
||||||
void setupBatchTransform(gpu::Batch& batch);
|
void setupBatchTransform(gpu::Batch& batch);
|
||||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||||
|
|
||||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
RenderArgs* args, Locations* locations, SkinLocations* skinLocations);
|
RenderArgs* args, Locations* locations, SkinLocations* skinLocations,
|
||||||
|
bool forceRenderSomeMeshes = false);
|
||||||
|
|
||||||
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||||
|
|
Loading…
Reference in a new issue