mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 13:13:02 +02:00
Merge pull request #15291 from luiscuenca/multiSpheresMixFix
Fix avatar multi-sphere bad scaling on some avatars
This commit is contained in:
commit
0e2c5ea3c2
3 changed files with 29 additions and 31 deletions
|
@ -1525,8 +1525,8 @@ void Avatar::rigReset() {
|
|||
|
||||
void Avatar::computeMultiSphereShapes() {
|
||||
const Rig& rig = getSkeletonModel()->getRig();
|
||||
glm::vec3 scale = extractScale(rig.getGeometryOffsetPose());
|
||||
const HFMModel& geometry = getSkeletonModel()->getHFMModel();
|
||||
glm::vec3 geometryScale = extractScale(rig.getGeometryOffsetPose());
|
||||
int jointCount = rig.getJointStateCount();
|
||||
_multiSphereShapes.clear();
|
||||
_multiSphereShapes.reserve(jointCount);
|
||||
|
@ -1535,9 +1535,10 @@ void Avatar::computeMultiSphereShapes() {
|
|||
std::vector<btVector3> btPoints;
|
||||
int lineCount = (int)shapeInfo.debugLines.size();
|
||||
btPoints.reserve(lineCount);
|
||||
glm::vec3 jointScale = rig.getJointPose(i).scale() / extractScale(rig.getGeometryToRigTransform());
|
||||
for (int j = 0; j < lineCount; j++) {
|
||||
const glm::vec3 &point = shapeInfo.debugLines[j];
|
||||
auto rigPoint = scale * point;
|
||||
auto rigPoint = jointScale * geometryScale * point;
|
||||
btVector3 btPoint = glmToBullet(rigPoint);
|
||||
btPoints.push_back(btPoint);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,14 @@ void SphereRegion::translate(const glm::vec3& translation) {
|
|||
line.second += translation;
|
||||
}
|
||||
}
|
||||
|
||||
void SphereRegion::scale(float scale) {
|
||||
for (auto &line : _lines) {
|
||||
line.first *= scale;
|
||||
line.second *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
void SphereRegion::dump(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines) {
|
||||
for (auto &line : _lines) {
|
||||
outLines.push_back(line);
|
||||
|
@ -127,7 +135,7 @@ bool MultiSphereShape::computeMultiSphereShape(int jointIndex, const QString& na
|
|||
_jointIndex = jointIndex;
|
||||
_name = name;
|
||||
_mode = getExtractionModeByName(_name);
|
||||
if (_mode == CollisionShapeExtractionMode::None || kdop.size() < 4 || kdop.size() > 200) {
|
||||
if (_mode == CollisionShapeExtractionMode::None || kdop.size() < 4) {
|
||||
return false;
|
||||
}
|
||||
std::vector<glm::vec3> points;
|
||||
|
@ -151,7 +159,9 @@ bool MultiSphereShape::computeMultiSphereShape(int jointIndex, const QString& na
|
|||
|
||||
_midPoint /= (int)points.size();
|
||||
glm::vec3 dimensions = max - min;
|
||||
|
||||
if (glm::length(dimensions) == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < points.size(); i++) {
|
||||
glm::vec3 relPoint = points[i] - _midPoint;
|
||||
relPoints.push_back(relPoint);
|
||||
|
@ -343,6 +353,7 @@ void MultiSphereShape::connectSpheres(int index1, int index2, bool onlyEdges) {
|
|||
}
|
||||
|
||||
void MultiSphereShape::calculateDebugLines() {
|
||||
std::vector<float> radiuses;
|
||||
if (_spheres.size() == 1) {
|
||||
auto sphere = _spheres[0];
|
||||
calculateSphereLines(_debugLines, sphere._position, sphere._radius);
|
||||
|
@ -351,41 +362,25 @@ void MultiSphereShape::calculateDebugLines() {
|
|||
} else if (_spheres.size() == 4) {
|
||||
std::vector<glm::vec3> axes;
|
||||
axes.resize(8);
|
||||
const float AXIS_DOT_THRESHOLD = 0.3f;
|
||||
for (size_t i = 0; i < CORNER_SIGNS.size(); i++) {
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
for (size_t j = 0; j < _spheres.size(); j++) {
|
||||
auto axis = _spheres[j]._position - _midPoint;
|
||||
glm::vec3 sign = { axis.x != 0.0f ? glm::abs(axis.x) / axis.x : 0.0f,
|
||||
axis.x != 0.0f ? glm::abs(axis.y) / axis.y : 0.0f ,
|
||||
axis.z != 0.0f ? glm::abs(axis.z) / axis.z : 0.0f };
|
||||
bool add = false;
|
||||
if (sign.x == 0.0f) {
|
||||
if (sign.y == CORNER_SIGNS[i].y && sign.z == CORNER_SIGNS[i].z) {
|
||||
add = true;
|
||||
}
|
||||
} else if (sign.y == 0.0f) {
|
||||
if (sign.x == CORNER_SIGNS[i].x && sign.z == CORNER_SIGNS[i].z) {
|
||||
add = true;
|
||||
}
|
||||
} else if (sign.z == 0.0f) {
|
||||
if (sign.x == CORNER_SIGNS[i].x && sign.y == CORNER_SIGNS[i].y) {
|
||||
add = true;
|
||||
}
|
||||
} else if (sign == CORNER_SIGNS[i]) {
|
||||
add = true;
|
||||
}
|
||||
if (add) {
|
||||
if (glm::length(axes[i]) == 0.0f && glm::length(axis) > 0.0f && glm::dot(CORNER_SIGNS[i], glm::normalize(axis)) > AXIS_DOT_THRESHOLD) {
|
||||
radiuses.push_back(_spheres[j]._radius);
|
||||
axes[i] = axis;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
calculateChamferBox(_debugLines, _spheres[0]._radius, axes, _midPoint);
|
||||
calculateChamferBox(_debugLines, radiuses, axes, _midPoint);
|
||||
} else if (_spheres.size() == 8) {
|
||||
std::vector<glm::vec3> axes;
|
||||
for (size_t i = 0; i < _spheres.size(); i++) {
|
||||
radiuses.push_back(_spheres[i]._radius);
|
||||
axes.push_back(_spheres[i]._position - _midPoint);
|
||||
}
|
||||
calculateChamferBox(_debugLines, _spheres[0]._radius, axes, _midPoint);
|
||||
calculateChamferBox(_debugLines, radiuses, axes, _midPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,9 +393,9 @@ void MultiSphereShape::connectEdges(std::vector<std::pair<glm::vec3, glm::vec3>>
|
|||
}
|
||||
}
|
||||
|
||||
void MultiSphereShape::calculateChamferBox(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const float& radius, const std::vector<glm::vec3>& axes, const glm::vec3& translation) {
|
||||
void MultiSphereShape::calculateChamferBox(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const std::vector<float>& radiuses, const std::vector<glm::vec3>& axes, const glm::vec3& translation) {
|
||||
std::vector<std::pair<glm::vec3, glm::vec3>> sphereLines;
|
||||
calculateSphereLines(sphereLines, glm::vec3(0.0f), radius);
|
||||
calculateSphereLines(sphereLines, glm::vec3(0.0f), radiuses[0]);
|
||||
|
||||
std::vector<SphereRegion> regions = {
|
||||
SphereRegion({ 1.0f, 1.0f, 1.0f }),
|
||||
|
@ -417,6 +412,7 @@ void MultiSphereShape::calculateChamferBox(std::vector<std::pair<glm::vec3, glm:
|
|||
|
||||
for (size_t i = 0; i < regions.size(); i++) {
|
||||
regions[i].extractSphereRegion(sphereLines);
|
||||
regions[i].scale(radiuses[i]/radiuses[0]);
|
||||
regions[i].translate(translation + axes[i]);
|
||||
regions[i].extractEdges(axes[i].y < 0);
|
||||
regions[i].dump(outLines);
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
void extractSphereRegion(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines);
|
||||
void extractEdges(bool reverseY = false);
|
||||
void translate(const glm::vec3& translation);
|
||||
void scale(float scale);
|
||||
void dump(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines);
|
||||
const glm::vec3& getDirection() const { return _direction; }
|
||||
const std::vector<glm::vec3>& getEdgesX() const { return _edgesX; }
|
||||
|
@ -94,7 +95,7 @@ private:
|
|||
void calculateSphereLines(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const glm::vec3& center, const float& radius,
|
||||
const int& subdivisions = DEFAULT_SPHERE_SUBDIVISIONS, const glm::vec3& direction = Vectors::UNIT_Y,
|
||||
const float& percentage = 1.0f, std::vector<glm::vec3>* edge = nullptr);
|
||||
void calculateChamferBox(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const float& radius, const std::vector<glm::vec3>& axes, const glm::vec3& translation);
|
||||
void calculateChamferBox(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const std::vector<float>& radiuses, const std::vector<glm::vec3>& axes, const glm::vec3& translation);
|
||||
void connectEdges(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const std::vector<glm::vec3>& edge1,
|
||||
const std::vector<glm::vec3>& edge2, bool reverse = false);
|
||||
void connectSpheres(int index1, int index2, bool onlyEdges = false);
|
||||
|
|
Loading…
Reference in a new issue