Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Everything posted by uglybdavis

  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. 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[120]; 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[120]; // 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?
  3. @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.
  4. 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...
  5. 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?
  6. uglybdavis

    Vector4 W Component

    Thanks guys! That pretty much answers all my questions!
  7. uglybdavis

    Vector4 W Component

    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?
  8. Thank you!   That has answered all of my questions. Thanks again, you have no idea how helpful that all was!
  9. 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 ); };  
  10. 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?
  11. 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?
  12. uglybdavis

    Game Engine for Linux

    @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.
  13. uglybdavis

    Game Engine for Linux

    Game Editor Blender Game Engine Godot C4
  14. 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.....
  15. uglybdavis

    C++ multiplatform engine/framework/library?

    Gameplay3D: http://gameplay3d.org/   Cross platform C++ gem!
  16. uglybdavis

    Good C (not C++) math library?

    Seeing how the glm source is available, why not copy-pasta the features you need? I've done this in the past and ended up with a small managable library of math code.
  17. uglybdavis

    noob question - dark basic

    It sounds like you're kind of a beginner, so welcome to the wonderful world of code!   For you, i'm going to go ahead and say the merits of a language should be gauged by the amount of information available targeting it rather than the complexity of learning it. Say you want to write some pathfinding code (Pretty important for an RTS game), i'm going to go out on a dime and say you can find more / better resources about pathfinding utilizing C# or Javascript than you could using any flavor of basic. Also keep in mind you are not interested in learning EVERY feature of C# or LUA, just the small subset that targets what you are trying to do.   Even simple projects are complicated to code, there is a lot of hidden complexity. I would suggest using a pre-made engine as you are not trying to showcase your code writing skills. There are a few good options for you, the two prominent ones are Unreal 4 (Blueprints), and Unity3D. I haven't used blueprints myself, but from what i gather so far it's super simple artist friendly visual coding. With Unity you will most likely have to learn C#, but there are a LOT of references online for this. Just take a look at the Packt Pub books. And the 2D unity tutorials / resources are just growing larger and larger.   Anyway, best of luck!
  18. http://msdn.microsoft.com/en-us/library/hbxc2t98(v=vs.84).aspx
  19. uglybdavis

    Dissecting idTech4

    Dissecting a production engine is never a fun learning experience. In production, things make it into code that shouldn't. That's just life.   How about starting with a more modern engine, that was made specifically to learn from:  https://github.com/blackberry/GamePlay   There is an older GDC video about it, but i lost the link.
  20. uglybdavis

    Visual Studio 2013 _tmain ?

    Thank you! That is the exact info i needed!!
  21. After several years of not using windows i find myself having to use visual studio 2013 (The last edition i used was visual studio 2008). To my surprise, my simple console application will not compile. It is complaining about a missing _tmain function. After checking out the default project that gets generated, i renames my main function from  int main(int argc, char *argv[]) { To int _tmain(int argc, _TCHAR* argv[]) { And everything now works...   When did this change happen? What was the reasoning behind this? Why not just keep regular old main?   Is there any way to use the standard main function? I hate having #if statements just for windows....   Can anyone please shed some light on this matter for me?
  22. uglybdavis

    Game engine

    Exactly what you are looking for: http://www.gameplay3d.org/
  23. uglybdavis

    2D rasterizer resources and book

    WHAT do you want to rasterize? IE, A single point, a line,  some 2D polyhedra, perhaps some font?   Each of these will have a different implementation. I suggest you start with how to rasterize a line. Plenty of online tutorials available for it. Read up on fill types and whatnot: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm http://ezekiel.vancouver.wsu.edu/~cs442/lectures/raster/polyfill/poly.pdf
  24. This: http://www.gameplay3d.org/
  25. This question relates to the lua c api. Lets say i have a file like this one:  helloString = "Hello World" function fwrite (fmt, ...) return io.write(string.format(fmt, unpack(arg))) end And i want to load it into a global table named loadedScript such that at a later point i can call fwrite like loadedScript.fwrite Ideally i would like to load the file and assign it's contents to the global table trough the C API.   I'm new to lua, and have no idea what to even look for to solve this. Anyone have any ideas?
  • 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!