mirror of
https://github.com/lubosz/overte.git
synced 2025-04-25 17:55:10 +02:00
Merge pull request #15296 from luiscuenca/kdopsRotOffsetFix
Add joint rotation offset to the avatar multi-sphere shapes
This commit is contained in:
commit
b8b7798ad9
5 changed files with 61 additions and 55 deletions
|
@ -300,8 +300,6 @@ QString getString(const QVariant& value) {
|
||||||
return list.isEmpty() ? value.toString() : list.at(0).toString();
|
return list.isEmpty() ? value.toString() : list.at(0).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector<glm::vec3> ShapeVertices;
|
|
||||||
|
|
||||||
class AnimationCurve {
|
class AnimationCurve {
|
||||||
public:
|
public:
|
||||||
QVector<float> values;
|
QVector<float> values;
|
||||||
|
@ -1352,8 +1350,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: shapeVertices are in joint-frame
|
// NOTE: shapeVertices are in joint-frame
|
||||||
std::vector<ShapeVertices> shapeVertices;
|
hfmModel.shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
|
||||||
shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
|
|
||||||
|
|
||||||
hfmModel.bindExtents.reset();
|
hfmModel.bindExtents.reset();
|
||||||
hfmModel.meshExtents.reset();
|
hfmModel.meshExtents.reset();
|
||||||
|
@ -1527,7 +1524,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
|
||||||
HFMJoint& joint = hfmModel.joints[jointIndex];
|
HFMJoint& joint = hfmModel.joints[jointIndex];
|
||||||
|
|
||||||
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
||||||
ShapeVertices& points = shapeVertices.at(jointIndex);
|
ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
|
||||||
|
|
||||||
for (int j = 0; j < cluster.indices.size(); j++) {
|
for (int j = 0; j < cluster.indices.size(); j++) {
|
||||||
int oldIndex = cluster.indices.at(j);
|
int oldIndex = cluster.indices.at(j);
|
||||||
|
@ -1601,7 +1598,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
|
||||||
|
|
||||||
// transform cluster vertices to joint-frame and save for later
|
// transform cluster vertices to joint-frame and save for later
|
||||||
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
|
||||||
ShapeVertices& points = shapeVertices.at(jointIndex);
|
ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
|
||||||
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
||||||
const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
|
const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
|
||||||
points.push_back(extractTranslation(vertexTransform));
|
points.push_back(extractTranslation(vertexTransform));
|
||||||
|
@ -1621,54 +1618,6 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
|
||||||
meshIDsToMeshIndices.insert(it.key(), meshIndex);
|
meshIDsToMeshIndices.insert(it.key(), meshIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float INV_SQRT_3 = 0.57735026918f;
|
|
||||||
ShapeVertices cardinalDirections = {
|
|
||||||
Vectors::UNIT_X,
|
|
||||||
Vectors::UNIT_Y,
|
|
||||||
Vectors::UNIT_Z,
|
|
||||||
glm::vec3(INV_SQRT_3, INV_SQRT_3, INV_SQRT_3),
|
|
||||||
glm::vec3(INV_SQRT_3, -INV_SQRT_3, INV_SQRT_3),
|
|
||||||
glm::vec3(INV_SQRT_3, INV_SQRT_3, -INV_SQRT_3),
|
|
||||||
glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
|
|
||||||
};
|
|
||||||
|
|
||||||
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
|
|
||||||
for (int i = 0; i < hfmModel.joints.size(); ++i) {
|
|
||||||
HFMJoint& joint = hfmModel.joints[i];
|
|
||||||
|
|
||||||
// NOTE: points are in joint-frame
|
|
||||||
ShapeVertices& points = shapeVertices.at(i);
|
|
||||||
if (points.size() > 0) {
|
|
||||||
// compute average point
|
|
||||||
glm::vec3 avgPoint = glm::vec3(0.0f);
|
|
||||||
for (uint32_t j = 0; j < points.size(); ++j) {
|
|
||||||
avgPoint += points[j];
|
|
||||||
}
|
|
||||||
avgPoint /= (float)points.size();
|
|
||||||
joint.shapeInfo.avgPoint = avgPoint;
|
|
||||||
|
|
||||||
// compute a k-Dop bounding volume
|
|
||||||
for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
|
|
||||||
float maxDot = -FLT_MAX;
|
|
||||||
float minDot = FLT_MIN;
|
|
||||||
for (uint32_t k = 0; k < points.size(); ++k) {
|
|
||||||
float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
|
|
||||||
if (kDot > maxDot) {
|
|
||||||
maxDot = kDot;
|
|
||||||
}
|
|
||||||
if (kDot < minDot) {
|
|
||||||
minDot = kDot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
|
|
||||||
joint.shapeInfo.dots.push_back(maxDot);
|
|
||||||
joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
|
|
||||||
joint.shapeInfo.dots.push_back(-minDot);
|
|
||||||
}
|
|
||||||
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to map any meshes to a named model
|
// attempt to map any meshes to a named model
|
||||||
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
|
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
|
||||||
m != meshIDsToMeshIndices.constEnd(); m++) {
|
m != meshIDsToMeshIndices.constEnd(); m++) {
|
||||||
|
|
|
@ -154,3 +154,55 @@ QString HFMModel::getModelNameOfMesh(int meshIndex) const {
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HFMModel::computeKdops() {
|
||||||
|
const float INV_SQRT_3 = 0.57735026918f;
|
||||||
|
ShapeVertices cardinalDirections = {
|
||||||
|
Vectors::UNIT_X,
|
||||||
|
Vectors::UNIT_Y,
|
||||||
|
Vectors::UNIT_Z,
|
||||||
|
glm::vec3(INV_SQRT_3, INV_SQRT_3, INV_SQRT_3),
|
||||||
|
glm::vec3(INV_SQRT_3, -INV_SQRT_3, INV_SQRT_3),
|
||||||
|
glm::vec3(INV_SQRT_3, INV_SQRT_3, -INV_SQRT_3),
|
||||||
|
glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
|
||||||
|
};
|
||||||
|
|
||||||
|
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
|
||||||
|
for (int i = 0; i < joints.size(); ++i) {
|
||||||
|
HFMJoint& joint = joints[i];
|
||||||
|
|
||||||
|
// NOTE: points are in joint-frame
|
||||||
|
ShapeVertices& points = shapeVertices.at(i);
|
||||||
|
glm::quat rotOffset = jointRotationOffsets.contains(i) ? glm::inverse(jointRotationOffsets[i]) : quat();
|
||||||
|
if (points.size() > 0) {
|
||||||
|
// compute average point
|
||||||
|
glm::vec3 avgPoint = glm::vec3(0.0f);
|
||||||
|
for (uint32_t j = 0; j < points.size(); ++j) {
|
||||||
|
points[j] = rotOffset * points[j];
|
||||||
|
avgPoint += points[j];
|
||||||
|
}
|
||||||
|
avgPoint /= (float)points.size();
|
||||||
|
joint.shapeInfo.avgPoint = avgPoint;
|
||||||
|
|
||||||
|
// compute a k-Dop bounding volume
|
||||||
|
for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
|
||||||
|
float maxDot = -FLT_MAX;
|
||||||
|
float minDot = FLT_MIN;
|
||||||
|
for (uint32_t k = 0; k < points.size(); ++k) {
|
||||||
|
float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
|
||||||
|
if (kDot > maxDot) {
|
||||||
|
maxDot = kDot;
|
||||||
|
}
|
||||||
|
if (kDot < minDot) {
|
||||||
|
minDot = kDot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
|
||||||
|
joint.shapeInfo.dots.push_back(maxDot);
|
||||||
|
joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
|
||||||
|
joint.shapeInfo.dots.push_back(-minDot);
|
||||||
|
}
|
||||||
|
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ using ColorType = glm::vec3;
|
||||||
|
|
||||||
const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
|
const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
|
||||||
|
|
||||||
|
|
||||||
|
using ShapeVertices = std::vector<glm::vec3>;
|
||||||
// The version of the Draco mesh binary data itself. See also: FBX_DRACO_MESH_VERSION in FBX.h
|
// The version of the Draco mesh binary data itself. See also: FBX_DRACO_MESH_VERSION in FBX.h
|
||||||
static const int DRACO_MESH_VERSION = 2;
|
static const int DRACO_MESH_VERSION = 2;
|
||||||
|
|
||||||
|
@ -327,10 +329,12 @@ public:
|
||||||
|
|
||||||
/// given a meshIndex this will return the name of the model that mesh belongs to if known
|
/// given a meshIndex this will return the name of the model that mesh belongs to if known
|
||||||
QString getModelNameOfMesh(int meshIndex) const;
|
QString getModelNameOfMesh(int meshIndex) const;
|
||||||
|
void computeKdops();
|
||||||
|
|
||||||
QList<QString> blendshapeChannelNames;
|
QList<QString> blendshapeChannelNames;
|
||||||
|
|
||||||
QMap<int, glm::quat> jointRotationOffsets;
|
QMap<int, glm::quat> jointRotationOffsets;
|
||||||
|
std::vector<ShapeVertices> shapeVertices;
|
||||||
FlowData flowData;
|
FlowData flowData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ namespace baker {
|
||||||
hfmModelOut->jointRotationOffsets = input.get3();
|
hfmModelOut->jointRotationOffsets = input.get3();
|
||||||
hfmModelOut->jointIndices = input.get4();
|
hfmModelOut->jointIndices = input.get4();
|
||||||
hfmModelOut->flowData = input.get5();
|
hfmModelOut->flowData = input.get5();
|
||||||
|
hfmModelOut->computeKdops();
|
||||||
output = hfmModelOut;
|
output = hfmModelOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -436,7 +436,7 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const
|
||||||
float z = scale.z;
|
float z = scale.z;
|
||||||
float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
|
float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
|
||||||
float halfHeight = 0.5f * scale.y - radius;
|
float halfHeight = 0.5f * scale.y - radius;
|
||||||
float MIN_HALF_HEIGHT = 0.1f;
|
float MIN_HALF_HEIGHT = 0.0f;
|
||||||
if (halfHeight < MIN_HALF_HEIGHT) {
|
if (halfHeight < MIN_HALF_HEIGHT) {
|
||||||
halfHeight = MIN_HALF_HEIGHT;
|
halfHeight = MIN_HALF_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue