mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
Basic attachment rendering.
This commit is contained in:
parent
65e34f9697
commit
f37460e39a
5 changed files with 76 additions and 22 deletions
|
@ -126,6 +126,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_skeletonModel.simulate(deltaTime);
|
_skeletonModel.simulate(deltaTime);
|
||||||
}
|
}
|
||||||
_skeletonModel.simulate(deltaTime, _hasNewJointRotations);
|
_skeletonModel.simulate(deltaTime, _hasNewJointRotations);
|
||||||
|
simulateAttachments(deltaTime, _hasNewJointRotations);
|
||||||
_hasNewJointRotations = false;
|
_hasNewJointRotations = false;
|
||||||
|
|
||||||
glm::vec3 headPosition = _position;
|
glm::vec3 headPosition = _position;
|
||||||
|
@ -338,6 +339,7 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_skeletonModel.render(1.0f, modelRenderMode);
|
_skeletonModel.render(1.0f, modelRenderMode);
|
||||||
|
renderAttachments(modelRenderMode);
|
||||||
getHand()->render(false);
|
getHand()->render(false);
|
||||||
}
|
}
|
||||||
getHead()->render(1.0f, modelRenderMode);
|
getHead()->render(1.0f, modelRenderMode);
|
||||||
|
@ -347,6 +349,32 @@ bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode render
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::simulateAttachments(float deltaTime, bool fullUpdate) {
|
||||||
|
if (!fullUpdate) {
|
||||||
|
return; // only simulate if we have new data
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _attachmentModels.size(); i++) {
|
||||||
|
const AttachmentData& attachment = _attachmentData.at(i);
|
||||||
|
Model* model = _attachmentModels.at(i);
|
||||||
|
int jointIndex = getJointIndex(attachment.jointName);
|
||||||
|
glm::vec3 jointPosition;
|
||||||
|
glm::quat jointRotation;
|
||||||
|
if (_skeletonModel.getJointPosition(jointIndex, jointPosition) &&
|
||||||
|
_skeletonModel.getJointRotation(jointIndex, jointRotation)) {
|
||||||
|
model->setTranslation(jointPosition + jointRotation * attachment.translation * _skeletonModel.getScale());
|
||||||
|
model->setRotation(jointRotation * attachment.rotation);
|
||||||
|
model->setScale(_skeletonModel.getScale() * attachment.scale);
|
||||||
|
model->simulate(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::renderAttachments(Model::RenderMode renderMode) {
|
||||||
|
foreach (Model* model, _attachmentModels) {
|
||||||
|
model->render(1.0f, renderMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::updateJointMappings() {
|
void Avatar::updateJointMappings() {
|
||||||
// no-op; joint mappings come from skeleton model
|
// no-op; joint mappings come from skeleton model
|
||||||
}
|
}
|
||||||
|
@ -667,6 +695,25 @@ void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
|
||||||
|
AvatarData::setAttachmentData(attachmentData);
|
||||||
|
|
||||||
|
// make sure we have as many models as attachments
|
||||||
|
while (_attachmentModels.size() < attachmentData.size()) {
|
||||||
|
Model* model = new Model(this);
|
||||||
|
model->init();
|
||||||
|
_attachmentModels.append(model);
|
||||||
|
}
|
||||||
|
while (_attachmentModels.size() > attachmentData.size()) {
|
||||||
|
delete _attachmentModels.takeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the urls
|
||||||
|
for (int i = 0; i < attachmentData.size(); i++) {
|
||||||
|
_attachmentModels[i]->setURL(attachmentData.at(i).modelURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::setDisplayName(const QString& displayName) {
|
void Avatar::setDisplayName(const QString& displayName) {
|
||||||
AvatarData::setDisplayName(displayName);
|
AvatarData::setDisplayName(displayName);
|
||||||
_displayNameBoundingRect = textRenderer(DISPLAYNAME)->metrics().tightBoundingRect(displayName);
|
_displayNameBoundingRect = textRenderer(DISPLAYNAME)->metrics().tightBoundingRect(displayName);
|
||||||
|
|
|
@ -131,6 +131,7 @@ public:
|
||||||
|
|
||||||
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||||
|
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData);
|
||||||
virtual void setDisplayName(const QString& displayName);
|
virtual void setDisplayName(const QString& displayName);
|
||||||
virtual void setBillboard(const QByteArray& billboard);
|
virtual void setBillboard(const QByteArray& billboard);
|
||||||
|
|
||||||
|
@ -160,6 +161,7 @@ signals:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkeletonModel _skeletonModel;
|
SkeletonModel _skeletonModel;
|
||||||
|
QVector<Model*> _attachmentModels;
|
||||||
float _bodyYawDelta;
|
float _bodyYawDelta;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
float _leanScale;
|
float _leanScale;
|
||||||
|
@ -188,6 +190,9 @@ protected:
|
||||||
virtual void renderBody(RenderMode renderMode, float glowLevel = 0.0f);
|
virtual void renderBody(RenderMode renderMode, float glowLevel = 0.0f);
|
||||||
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||||
|
|
||||||
|
void simulateAttachments(float deltaTime, bool fullUpdate = true);
|
||||||
|
void renderAttachments(Model::RenderMode renderMode);
|
||||||
|
|
||||||
virtual void updateJointMappings();
|
virtual void updateJointMappings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -244,6 +244,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
getHand()->simulate(deltaTime, true);
|
getHand()->simulate(deltaTime, true);
|
||||||
|
|
||||||
_skeletonModel.simulate(deltaTime);
|
_skeletonModel.simulate(deltaTime);
|
||||||
|
simulateAttachments(deltaTime);
|
||||||
|
|
||||||
// copy out the skeleton joints from the model
|
// copy out the skeleton joints from the model
|
||||||
_jointData.resize(_skeletonModel.getJointStateCount());
|
_jointData.resize(_skeletonModel.getJointStateCount());
|
||||||
|
@ -657,7 +658,8 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
|
||||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||||
_skeletonModel.render(1.0f, modelRenderMode);
|
_skeletonModel.render(1.0f, modelRenderMode);
|
||||||
|
renderAttachments(modelRenderMode);
|
||||||
|
|
||||||
// Render head so long as the camera isn't inside it
|
// Render head so long as the camera isn't inside it
|
||||||
if (shouldRenderHead(Application::getInstance()->getCamera()->getPosition(), renderMode)) {
|
if (shouldRenderHead(Application::getInstance()->getCamera()->getPosition(), renderMode)) {
|
||||||
getHead()->render(1.0f, modelRenderMode);
|
getHead()->render(1.0f, modelRenderMode);
|
||||||
|
|
|
@ -509,6 +509,24 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Model::getJointPosition(int jointIndex, glm::vec3& position) const {
|
||||||
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
position = _translation + extractTranslation(_jointStates[jointIndex].transform);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Model::getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind) const {
|
||||||
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rotation = _jointStates[jointIndex].combinedRotation *
|
||||||
|
(fromBind ? _geometry->getFBXGeometry().joints[jointIndex].inverseBindRotation :
|
||||||
|
_geometry->getFBXGeometry().joints[jointIndex].inverseDefaultRotation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::clearShapes() {
|
void Model::clearShapes() {
|
||||||
for (int i = 0; i < _jointShapes.size(); ++i) {
|
for (int i = 0; i < _jointShapes.size(); ++i) {
|
||||||
delete _jointShapes[i];
|
delete _jointShapes[i];
|
||||||
|
@ -957,24 +975,6 @@ void Model::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint
|
||||||
// nothing by default
|
// nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::getJointPosition(int jointIndex, glm::vec3& position) const {
|
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
position = _translation + extractTranslation(_jointStates[jointIndex].transform);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Model::getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind) const {
|
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
rotation = _jointStates[jointIndex].combinedRotation *
|
|
||||||
(fromBind ? _geometry->getFBXGeometry().joints[jointIndex].inverseBindRotation :
|
|
||||||
_geometry->getFBXGeometry().joints[jointIndex].inverseDefaultRotation);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation, bool useRotation,
|
bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation, bool useRotation,
|
||||||
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment) {
|
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment) {
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
|
|
|
@ -180,6 +180,9 @@ public:
|
||||||
/// Returns the extended length from the right hand to its first free ancestor.
|
/// Returns the extended length from the right hand to its first free ancestor.
|
||||||
float getRightArmLength() const;
|
float getRightArmLength() const;
|
||||||
|
|
||||||
|
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
||||||
|
bool getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind = false) const;
|
||||||
|
|
||||||
void clearShapes();
|
void clearShapes();
|
||||||
void rebuildShapes();
|
void rebuildShapes();
|
||||||
void updateShapePositions();
|
void updateShapePositions();
|
||||||
|
@ -269,9 +272,6 @@ protected:
|
||||||
virtual void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state);
|
virtual void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state);
|
||||||
virtual void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state);
|
virtual void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state);
|
||||||
|
|
||||||
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
|
||||||
bool getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind = false) const;
|
|
||||||
|
|
||||||
bool setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation = glm::quat(),
|
bool setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation = glm::quat(),
|
||||||
bool useRotation = false, int lastFreeIndex = -1, bool allIntermediatesFree = false,
|
bool useRotation = false, int lastFreeIndex = -1, bool allIntermediatesFree = false,
|
||||||
const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f));
|
const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f));
|
||||||
|
|
Loading…
Reference in a new issue