Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rendering): replicate SkeletalMesh fields, fix debug skeleton scale #4897

Merged

Conversation

pollend
Copy link
Member

@pollend pollend commented Sep 7, 2021

I fixed two things, I corrected the debug display for the skeleton render and made sure to make scale and translate as replicated so this should fix the offset animated meshes in MetalRenegades.

I think we need to re-think how this works at the moment because there is a lot of back and forth between SkeletonRender <--> OpenGLSkeletalMesh <--> SkeletalMeshData. The coupling is very tight and a lot of state information is funneled between these three classes. I'm finding it hard to see how this fits together with how this is organized at the moment.

@github-actions github-actions bot added the Type: Bug Issues reporting and PRs fixing problems label Sep 7, 2021
Comment on lines 348 to 350
Vector3f location = locationComponent.getWorldPosition(new Vector3f());
Quaternionf rotation = locationComponent.getWorldRotation(new Quaternionf());
Matrix4f transform = new Matrix4f().translationRotateScale(location, rotation, 1.0f);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to create new instances for the location vector, the rotation quaternion, and the transformation matrix with each render call for each entity?

You often raise concerns about code like this, so I'm wondering about all the instantiations in this code render code block that gets called quite often (if the debug feature is enabled).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umm, I guess I could use a temporary Matrix. this is because we have custom offset and translation for the SkeletonComponent :/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we need individual vectors here and cannot reuse a single temporary object instance for rendering the skeleton for all entities?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, we can cache it, I was just getting lazy. was looking at this at 10 something.

@skaldarnar skaldarnar added the Topic: Rendering Requests, Issues and Changes related to lighting, meshes, camera, etc. label Sep 7, 2021
@skaldarnar skaldarnar changed the title bugfix: resolve SkeletonRenderer for multiplayer and correct debug skeleton fix(rendering): replicate SkeletalMesh fields and correctly scale debug skeleton Sep 7, 2021
…f github.com:MovingBlocks/Terasology into bugfix/correct-SkeletonRenderer-debug-resolve-update
@jdrueckert
Copy link
Member

jdrueckert commented Sep 29, 2021

I'm not sure this works correctly yet 🤔
In-game I saw the following:
image

Note that the debug skeleton seems to be higher in the air than the actual model. @pollend did you only correct scaling the debug skeleton or also applying an offset?

…f github.com:MovingBlocks/Terasology into bugfix/correct-SkeletonRenderer-debug-resolve-update
@pollend
Copy link
Member Author

pollend commented Oct 3, 2021

@jdrueckert this fixes the offset in the overlay rig but this kind of horrible so this offset will just offset the camera space and additionally we also have an additional translation on top of the rig itself to also offset things. everything in the cameras view for the rig is offset by that amount. not sure if that lines up with world coordinates at all?

Copy link
Member

@jdrueckert jdrueckert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all it's hard for me to review this because I don't understand the math behind this, so please add comments especially in the new code in SkeletonRenderer that explain what the respective parts do.

Second, why do we need to offset the camera to have the debug skeleton match the actual one the model is matching? This does not seem to make sense to me? Where does this mismatch between debug skeleton and model come from? Is the model not matching the skeleton or is the rendered debug skeleton not matching the "real" skeleton?

Third, there's open checkstyle warnings.

@pollend
Copy link
Member Author

pollend commented Oct 30, 2021

First of all it's hard for me to review this because I don't understand the math behind this, so please add comments especially in the new code in SkeletonRenderer that explain what the respective parts do.

Second, why do we need to offset the camera to have the debug skeleton match the actual one the model is matching? This does not seem to make sense to me? Where does this mismatch between debug skeleton and model come from? Is the model not matching the skeleton or is the rendered debug skeleton not matching the "real" skeleton?

Third, there's open checkstyle warnings.

there is some code up a couple lines I'm just duplicating that logic.

@jdrueckert
Copy link
Member

First of all it's hard for me to review this because I don't understand the math behind this, so please add comments especially in the new code in SkeletonRenderer that explain what the respective parts do.
Second, why do we need to offset the camera to have the debug skeleton match the actual one the model is matching? This does not seem to make sense to me? Where does this mismatch between debug skeleton and model come from? Is the model not matching the skeleton or is the rendered debug skeleton not matching the "real" skeleton?
Third, there's open checkstyle warnings.

there is some code up a couple lines I'm just duplicating that logic.

Can you please note on which of my three points you're talking about and reference specific lines?

@pollend
Copy link
Member Author

pollend commented Oct 30, 2021

looks like I applied heightoffset twice

Copy link
Member

@jdrueckert jdrueckert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests out fine in-game now, but I think we can improve on documentation here while we're at it 🙏

Comment on lines 351 to 353
Vector3f worldPos = new Vector3f();
Vector3f worldPositionCameraSpace = new Vector3f();
worldPos.sub(cameraPosition, worldPositionCameraSpace);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit lengthy for

Suggested change
Vector3f worldPos = new Vector3f();
Vector3f worldPositionCameraSpace = new Vector3f();
worldPos.sub(cameraPosition, worldPositionCameraSpace);
Vector3f worldPositionCameraSpace = cameraPosition.negate(new Vector3f());

Comment on lines 347 to 362
Vector3f location = locationComponent.getWorldPosition(new Vector3f());
Quaternionf rotation = locationComponent.getWorldRotation(new Quaternionf());
entityTransform.translationRotateScale(location, rotation, 1.0f);

Vector3f worldPos = new Vector3f();
Vector3f worldPositionCameraSpace = new Vector3f();
worldPos.sub(cameraPosition, worldPositionCameraSpace);

// same heightOffset is applied to worldPositionCameraSpace from #renderOpaque()
// TODO: resolve repeated logic for transformation applied to bones
worldPositionCameraSpace.y += skeletalMesh.heightOffset;

Matrix4f matrixCameraSpace = new Matrix4f().translationRotateScale(worldPositionCameraSpace, new Quaternionf(), 1.0f);
Matrix4f modelViewMatrix = new Matrix4f(worldRenderer.getActiveCamera().getViewMatrix()).mul(matrixCameraSpace);
material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix());
material.setMatrix4("modelViewMatrix", modelViewMatrix, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As somebody that never really paid a lot of attention in my university computer graphics course, this is all Greek to me... can you please add some comments explaining what's happening here and why?

Comment on lines 375 to 393
locCompA.getRelativeTransform(relMat.identity(), entity);
result.set(entityTransform)
.mul(relFinal.identity()
.scale(skeletalMesh.scale)
.translate(skeletalMesh.translate)
.mul(relMat))
.transformPosition(currentPos.zero());
meshData.position.put(currentPos);


locCompB.getRelativeTransform(relMat.identity(), entity);
result.set(entityTransform)
.mul(relFinal
.identity()
.scale(skeletalMesh.scale)
.translate(skeletalMesh.translate)
.mul(relMat))
.transformPosition(currentPos.zero());
meshData.position.put(currentPos);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here pls

pollend and others added 3 commits November 7, 2021 17:00
…f github.com:MovingBlocks/Terasology into bugfix/correct-SkeletonRenderer-debug-resolve-update
Copy link
Member

@jdrueckert jdrueckert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the improved code comments! They are way more helpful!

Comment on lines 375 to 395
locCompA.getRelativeTransform(relMat.identity(), entity);
// entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
result.set(entityTransform)
.mul(relFinal.identity()
.scale(skeletalMesh.scale)
.translate(skeletalMesh.translate)
.mul(relMat)) // apply relative transformation for the skeletalMesh scale and transform
.transformPosition(currentPos.zero());
meshData.position.put(currentPos);
.mul(relMat))
.transformPosition(currentPos.zero()); // get the position of the start of the bone
meshData.position.put(currentPos); // the start of the bone

// relative transform around the root skeletalMesh.scale and skeletalMesh.translate are relative to root
// need to calculate the relative transformation from the entity to the connecting bone
locCompB.getRelativeTransform(relMat.identity(), entity);
// entityTransform * (scale, translation) * relativeMat * [x,y,z,1]
result.set(entityTransform)
.mul(relFinal
.identity()
.scale(skeletalMesh.scale)
.translate(skeletalMesh.translate)
.mul(relMat)) // apply relative transformation for the skeletalMesh scale and transform
.transformPosition(currentPos.zero());
meshData.position.put(currentPos);
.mul(relMat))
.transformPosition(currentPos.zero()); // get the position to the connecting bone
meshData.position.put(currentPos); // the end of the bone
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those two sections seem to do pretty much the same apart from the difference between locCompA and locCompB which according to the doc comments are the start of the bone vs the connecting bone.
Do you think it would make sense to extract this into a separate function and call it with the respective locComp?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would require passing a lot of parameters. Will be overhauled by @pollend soon-ish anyway, at which point we should ensure a comprehensible structure of the logic. Accepting it as is for now.

@jdrueckert jdrueckert changed the title fix(rendering): replicate SkeletalMesh fields and correctly scale debug skeleton fix(rendering): replicate SkeletalMesh fields, fix debug skeleton scale Nov 14, 2021
@jdrueckert jdrueckert merged commit f105255 into develop Nov 14, 2021
@jdrueckert jdrueckert deleted the bugfix/correct-SkeletonRenderer-debug-resolve-update branch November 14, 2021 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Topic: Rendering Requests, Issues and Changes related to lighting, meshes, camera, etc. Type: Bug Issues reporting and PRs fixing problems
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants