Demo: Green Dragon

Articles with the tag: 3D Graphics

CharSim: release and summary

System architecture for version 001

What I planned in the spec is now complete and ready for release. The GLSL shaders now work at version level 120 (compatible with OpenGL 2.2) in order to support older graphics cards.

What has been the point of the project?

  • Am familiarised with 3D APIs and shaders.
  • Have explored and incorporated third-party libraries.
  • Learn and apply knowledge of mathematics and algorithms for a technical animation framework and basic game engine.
  • Handle debugging using exception handling and gdb.
  • Designed an object-oriented framework model.
  • Used C++ standard library tools (smart pointers to automatically refcount resource objects, lambda functions and their relation to STL algorithms, vectors, lists, maps, iterators).
  • Explored C++ design patterns (abstract classes used as interfaces, compositing and inheritance patterns).
  • Have worked with the distributed version control system Git for revisions and distribution.

Of course there are many features I still want to explore ...

Read More »

Character skinning: finding rotation between vectors

Solving the angle problem: How to find the rotation between two vectors.

This solution is implemented in the Math class and will be invoked by the bezier curve-following IK method in the SkeletonNode class.

Given two normalised vectors, the cosine of the angle between them can be found using the dot product:

quat rotation(vec3 v1, vec3 v2)
    // v1 dot v2 = |v1| * |v2| * angle_cos
    // If the vectors are normalised, their magnitudes will be '1', and so:
    v1 = normalise(v1)
    v2 = normalise(v2)
    float angle_cos = dot(v1, v2)

The rotation axis can be found using the cross product of both vectors:

...rotation() cont'd...
vec3 axis = normalise(cross(v1, v2))

Optimal forms for creating quaternion:

Naive rotation() method (ignoring special cases such as angle=0):

...rotation() cont'd...
float angle = acos(angle_cos)
return quaternion_from_axisangle(angle, axis)

The quaternion_from_axisangle() function likely uses trigonometry (such as the cosine function) to convert the given ...

Read More »

Collision detection: Armature-curve alignment (for Bézier curve-based IK method)

Hang on, if the quadratic equation is used on a finite line which doesn't completely go through the sphere (partial intersection)... how many roots will there be? I will calculate a test case by hand. Obviously the quadratic equation will product two roots, but a way of discerning the physically realistic roots would be useful.

Also, what to do if the sphere really does go through a joint twice? Simple:
The value returned by the quadratic equation is the parameter (is it normalised?). The value closest to unity will represent a point further along the curve segment.

[10/05/14 11:00]

Testing partial intersection by calculating roots between a finite line and a circle and graphing the results.

Conjecture: the root most suitable to represent the parameter t along the line will exist in the range [0, 1].

Intersections between a line of finite length and a circle ...

Read More »

Inverse kinematics: IK solvers

Looking at IK (Inverse Kinematics) solving techniques for interactive armature animation. IK works well in games when interacting with a non-branching chain of joints, say an NPC's arm. In the case of my demo character, the dragon's neck is a perfect example of where some form of IK can make a rigged character interactive.

[16/04/14 14:08]

Here is a Gradient-following method.

The direction of each joint to move in depends on the calculated gradient, either by moving the joint a bit ("Gradient by Measurement") or calculating the gradient directly using differentiation ("Gradient by Calculation").

I am presuming the second method's dot product returns a positive or negative gradient which denotes the direction the joint should move in.

Being a 3D simulation, each joint in my demo has directional freedom in the range of 0-360 degrees. In order to reduce the number of possible directions ...

Read More »

Armature animation: extracting bone rotation data

ASSIMP just won't read my COLLADA file. Manually entering values from XML to see if the bone matrix values do anything. If so, can use an XML parser instead of ASSIMP.

First (root) bone from COLLADA XML file:

<COLLADA xmlns="http://www.COLLADA.org/2005/11/COLLADASchema" version="1.4.1">
<source id="Armature_Bone_pose_matrix-output">
    <float_array id="Armature_Bone_pose_matrix-output-array" count="32">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.9937479 -0.111412 0.007234246 0 0.111412 0.9853772 -0.1289153 0 0.007234247 0.1289153 0.9916292 0 0 0 0 1</float_array>
      <accessor source="#Armature_Bone_pose_matrix-output-array" count="2" stride="16">
        <param name="TRANSFORM" type="float4x4"/>

Whelp, you can't reverse-engineer an XYZ-rotation matrix. Can try to use it directly, but that removes quaternion SLERP rotation.

Turns out you can:

R = r11 r12 r13
    r21 r22 r23
    r31 ...

Read More »

Lights, cameras, and rendering

Implementing SceneGraph, SceneNodes and Renderer.

Camera is inserted into SceneGraph so objects can descend from it (so they are relative to camera) and the camera can be stuck onto other objects, so CameraNode passes world_transformation matrix like any other.

However, camera also contains view_transform and can be grabbed by the Renderer using SceneGraph's Find command.

Similarly lights are in the SceneGraph, but can be grabbed by the Renderer for shading input. Not sure if shaders can be made to handle a varying number of lights.

If ModelNodes send things to Renderer... could lights send themselves to Renderer each time? It would have to be done as part of the update process. Must make sure Renderer/Shaders can handle arbitrary lighting before bothering to implement.

[13/03/14 20:30]

SceneGraph should have update() and update_all(). The latter contains standard code for updating the leaf nodes, and then the update ...

Read More »

Page 1 / 2 Older »