Jump to content
• Advertisement  # uglybdavis

Member

156

1066 Excellent

• Rank
Member

## Personal Information

• Interests
DevOps
1. When looking at bezier curves, it's easy to understand them intuitively as a few lerps between points. And they are fairly trivial to implement this way. Vector3 SampleCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) { Vector3 q0 = Lerp(p0, p1, t); Vector3 q1 = Lerp(p1, p2, t); Vector3 q2 = Lerp(p3, p3, t); Vector3 r0 = Lerp(q0, q1, t); Vevtor3 r1 = Lerp(q1, q2, t); return Lerp(r0, r1, t); } From what i gather, the above is called de Casteljau's method. However, you could also evaluate them using the bezier basis functions: p = (1-t)^3 *P0 + 3*t*(1-t)^2*P1 + 3*t^2*(1-t)*P2 + t^3*P3 Which is a lot less intuitive, but at least i can find some nice graphics to explain how the functions work: When looking at cubic hermite splines, the only info i seem to find online is the less than intuitive basis funtions: Implemented with some less than intuitive code: float Hermite(float t, float p0, float m0, float p1, float m1) { float tt = t * t; float ttt = t * t * t; return (2.0f * ttt - 3.0f * tt + 1.0f) * p0 + (ttt - 2.0f * tt + t) * m0 + (-2.0f * ttt + 3.0f * tt) * p1 + (ttt - tt) * m1; } Is there an intuitive, easy to explain way of interpolating cubic hermite splines similar to that of bezier curves? Maybe it's not just a few lerps, but it would really help to know if there is a way to explain this that doesn't involve having to look at the graph of basis functions....
2. @JohnnyCode you where right. It looked correct, but examining the skeleton, it sure wasn't. Image attached. Green skeleton is linearly blending the final matrices. Red skeleton is blending the joints components before they get turned into matrices.
3. I mean, that's what blending is, a linear combination. So, to blend two poses, it would just be linearly combining the matrices... So, to blend two poses we'd have two arrays of matrices in world space, one that's walking, one that's idling. Then we'd do a linear blend between them. The resulting blended matrix would then be passed to the shader... // inBlend1 is in the range of 0 to 1 // inBlend2 = (1.0f - inBlend1) void BlendPoses(vector<mat4> &outPose, vector<mat4> &inPose1, vetor<mat4> &inPose2, float inBlend1, float inBlend2) { for (int i = 0, size = outPose.size(); i < size; ++i) { outPose[i] = (inPose1[i] * inBlend1) + (inPose2[i] * inBlend2); } } So, i did just that, potato quality gif attached. I'm not really understanding the problem, maybe we're considering poses different things? So long as the pose is an array of world space matrices which contains only linear transforms (position, rotation, scale), this should work right? I think blending animations should just be a problem of averaging some number of matrices together for each joint.... I guess next steps are going to be to make a sample that blends poses both this way and at the joint component level (before they are converted to matrices) and see if they are different or the same. I don't have any examples of complex animations that do both rotation, translation an scale tough, most of the samples i have are orientation only...
4. Wow, that's pretty interesting, i didn't expect it to work like that. Thank you for the thorough example! I assume this means if i have two unrelated skeleton poses (bunch of matrices in world space), i could multiply them together like this to blend them. Would there be any downside to doing that compared to blending the position / rotation / scale components that make up the matrices in joint local space?
5. I have a quick question on matrix palette skinning. I have the following shared which handles my skinning as expected. It skins the vertex to each bone, then multiplies the skinned position by weight: #version 330 core uniform mat4 view; uniform mat4 model; uniform mat4 projection; uniform mat4 skeleton; in vec3 position; in vec2 texcoord; in ivec4 bones; in vec4 weights; out vec2 uv; void main() { vec4 pos = vec4(position.x, position.y, position.z, 1.0); vec4 vertex = vec4(0.0f, 0.0f, 0.0f, 0.0f); vertex += (skeleton[bones.x] * pos) * weights.x; vertex += (skeleton[bones.y] * pos) * weights.y; vertex += (skeleton[bones.z] * pos) * weights.z; vertex += (skeleton[bones.w] * pos) * weights.w; vertex.w = 1.0f; gl_Position = projection * view * model * vertex; uv = texcoord; } Whats confusing me is i can change this to scale & add the matrices, which yields the exact same results?!? #version 330 core uniform mat4 view; uniform mat4 model; uniform mat4 projection; uniform mat4 skeleton; // matrix pallete for skinning in vec3 position; in vec2 texcoord; in ivec4 bones; in vec4 weights; out vec2 uv; void main() { vec4 pos = vec4(position.x, position.y, position.z, 1.0); mat4 pallete = skeleton[bones.x] * weights.x; pallete += skeleton[bones.y] * weights.y; pallete += skeleton[bones.z] * weights.z; pallete += skeleton[bones.w] * weights.w; gl_Position = projection * view * model * pallete * pos; uv = texcoord; } I don't understand why the second version woks at all. I assumed since the upper 3x3 matrix contains both scale and rotation, doing this would introduce artifacts, but it doesn't.... Does anyone have any insight into why this might be? is blending matrices in this fashion safe / acceptable?
6. I'm working on a Vector4 class, and am having a hard time figuring out what to do with the W Component.   To my understanding if W is 0, the vector is treated as a vector when being multiplied by a matrix. That is, it will not be translated, only rotated and scaled. If the W is 1, the vector is treated as a point when being multiplied by a matrix. That is, it will be translated, rotated and scaled!   So, what vector operations does W take part in exactly? I assume not length.... It would be odd if W took part in the Length operation as the vector (2, 2, 2, 0) and the point (2, 2, 2, 1) would have different results.   On that same note, it does not make sense (to me) to include W in the dot product calculation either.    So, should i just ignore W for these operations: Addition, Subtraction, Scalar Multiplication, Dot Product, Cross Product, Length and Projection?   But then what happens when a Vector with a W of 0 and a Vector with a W of 1 are added? Point + Vector = Point makes sense in my head. But Vector + Point = ? That doesn't really make much sense...   Does this make sense to anyone else? How do you handle the W component of a Vector4?
7. Thank you!   That has answered all of my questions. Thanks again, you have no idea how helpful that all was!
8. That's very helpful.    If i understand what you said correctly, if two matrices (A and B) together; to find element 2,3 of the resulting matrix   Row major multiplication: take the dot product row 2 of matrix A and column 3 of matrix B   Column major multiplication: take the dot product of column 2 of matrix A, and row 3 of matrix B   ----------------------------------------   So, last question (i hope). Does the above mean that the formula for matrix product (For matrices F & G):   This will always take dot product the i-th row and j-th column of the two matrices, the only difference being that row major = FG, while column major = GF   OR, do the subscripts get a different meaning? Like in row major it's the i-th row and j-th column, where with column major it's the j-th row and i-th column?
9. I see, thank you for clearing that up.    If i understand correctly, the transpose is a result of treating the vector as a column vector; hence the matrix is never actually transposed. Is that correct?   I have one more question regarding pre / post multiplication. I always assumed that the whole row v column order was what determined if pre or post multiplication is used (Due largely to my understanding of linear algebra being based on the differences in OpenGL & Direct X).    Now that i'm trying to build some more solid mathematical foundations i find my old understanding very chalenged.   If we have Matrix T (a translation matrix that translates by 10, 20 and 30)  and matrix S (A scale matrix that is a uniform scale of two)   And we want to concatinate the transformation so that the matrix translates first, and scales second we must calculate it as S x T. This is assuming the same multiplication method as in the first post. I think because we scaled first then translated this is using post multiplication?   If correct, how come post multiplying two row major matrices works in math but Direct 3D uses pre-multiplication? Is this due to some implicit like the vector X matrix multiplication? Am i missing something trivial in my mental model of how this works?   Or perhaps is my pre / post terminology wrong when it comes to multiplying matrices?
10. I'm hoping someone could clear up a bit of matrix confusion i'm having. The breakdown might be because of my understanding of math or direct x but here goes.   As i understand Direct3D is often using a left handed coordinate system, row major matrices and row vectors with pre multiplication.   pre multiplication meaning that the vector being multiplied goes before the matrix. IE: transformedVector = vector * matrix;   Now as far as i understand given matrices A * B, to calculate the matrix product of element 2, 3 you take the dot product of the second row of A and 3rd column of B. This means that A and B's inner dimensions must match, and their outer dimensions will be the size of the resulting matrix.   With the above rules in mind given a row vector (4, 1) and a transformation matrix (4, 4) the only way to get a row vector as the result is to use post multiplication. That is transformedVector = matrix * vector.   So, given this information how on earth does DirectX use pre multiplication? Do they not follow the row / column rules of the dot product and in effect transpose the vector or matrix?   Context: HLSL, Direct 3D 9: https://msdn.microsoft.com/en-us/library/windows/desktop/bb944006(v=vs.85).aspx float4 VertexShader_Tutorial_1(float4 inPos : POSITION ) : POSITION { return mul(inPos, WorldViewProj ); };
11. @phantom I totally forgot UE4 is on linux now!   @alnite It's just in blender. You're gonna have to do some googling. Tough as phantom pointed out, UE4 man! Should be super quick to prototype with blueprints.
12. I'm a bit confused. I keep reading the following: OpenGL uses a right-handed coordinate system, column-major matrices, column vectors, and post-multiplication.   Yet the in memory layout of an OpenGL matrix is: x.x x.y x.z 0 y.x y.y y.z 0 z.x z.y z.z 0 p.x p.y p.z 1 Or x.x x.y x.z 0 y.x y.y y.z 0 z.x z.y z.z 0 p.x p.y p.z 1 Which is a row major layout!   I'm trying to roll my own math library, looking at glm for guidance, matrices are indexed as mat[row][col] which would seem to only further strengthen that OpenGL is indeed using row matrices.   It sounds like the matrix notation used in the OpenGL docs (and blue book) does not describe the in memory layout of the matrices. Which begs the question, does this mean i should be pre-multiplying matrices, or do i need to account for the in-memory layout when doing matrix multiplications and keep post-multiply?   again, turning to glm for help, if i want to translate a model to 1, 2, 3 and then scale it up by 2 i need to do post multiplication: glm::mat4 mat = glm::translate(glm::vec3(1.0f, 2.0f, 3.0f)) * glm::scale(glm::vec3(2.0f, 2.0f, 2.0f)); Results in: 2, 0, 0, 0,  0, 2, 0, 0,  0, 0, 2, 0,  1, 2, 3, 1 But, if the matrix has a row layout, shouldn't that multiplication be in reverse?   So confused.....
13. Gameplay3D: http://gameplay3d.org/   Cross platform C++ gem!
• Advertisement
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!