Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "Headers/AnimationEvaluator.h"
#include "Headers/AnimationUtils.h"
#include "Platform/Video/Headers/GFXDevice.h"

#include "Core/Headers/Console.h"
#include "Utility/Headers/Localization.h"

namespace Divide {

// ------------------------------------------------------------------------------------------------
// Constructor on a given animation.
AnimEvaluator::AnimEvaluator( const aiAnimation* pAnim) {
	_lastTime = 0.0;
	_ticksPerSecond = pAnim->mTicksPerSecond != 0.0f ? pAnim->mTicksPerSecond : ANIMATION_TICKS_PER_SECOND;
	_duration = pAnim->mDuration;
	_name = pAnim->mName.data;

	D_PRINT_FN(Locale::get("CREATE_ANIMATION_BEGIN"),_name.c_str());

	_channels.resize(pAnim->mNumChannels);
	for( U32 a = 0; a < pAnim->mNumChannels; a++){
		_channels[a]._name = pAnim->mChannels[a]->mNodeName.data;
		for (U32 i(0); i < pAnim->mChannels[a]->mNumPositionKeys; i++) {
			_channels[a]._positionKeys.push_back(pAnim->mChannels[a]->mPositionKeys[i]);
		}
		for (U32 i(0); i < pAnim->mChannels[a]->mNumRotationKeys; i++) {
			_channels[a]._rotationKeys.push_back(pAnim->mChannels[a]->mRotationKeys[i]);
		}
		for (U32 i(0); i < pAnim->mChannels[a]->mNumScalingKeys; i++) {
			_channels[a]._scalingKeys.push_back(pAnim->mChannels[a]->mScalingKeys[i]);
		}
		_channels[a]._numPositionKeys = pAnim->mChannels[a]->mNumPositionKeys;
		_channels[a]._numRotationKeys = pAnim->mChannels[a]->mNumRotationKeys;
		_channels[a]._numScalingKeys  = pAnim->mChannels[a]->mNumScalingKeys;
	}

	_lastPositions.resize( pAnim->mNumChannels, vec3<U32>());

	D_PRINT_FN(Locale::get("CREATE_ANIMATION_END"), _name.c_str());
}

I32 AnimEvaluator::GetFrameIndexAt(const D32 elapsedTime){
	// get a [0.f ... 1.f) value by allowing the percent to wrap around 1
	D32 ptime = elapsedTime * _ticksPerSecond;

	D32 time = 0.0f;
	if( _duration > 0.0)
		time = fmod( ptime, _duration);

	F32 percent = time / _duration;

	if(!_playAnimationForward)
        percent= (percent-1.0f)*-1.0f;// this will invert the percent so the animation plays backwards

	_lastFrameIndex = std::min(static_cast<I32>(_transforms.size() * percent), static_cast<I32>(_transforms.size() - 1));

	return _lastFrameIndex;
}

// ------------------------------------------------------------------------------------------------
// Evaluates the animation tracks for a given time stamp.
void AnimEvaluator::Evaluate(const D32 dt, hashMapImpl<stringImpl, Bone*>& bones) {
	D32 pTime = dt * _ticksPerSecond;

	D32 time = 0.0f;
	if( _duration > 0.0)
		time = fmod( pTime, _duration);
	GetFrameIndexAt(pTime);
	hashMapImpl<stringImpl, Bone*>::iterator bonenode;
	// calculate the transformations for each animation channel
	for( U32 a = 0; a < _channels.size(); a++){
		const AnimationChannel* channel = &_channels[a];
		bonenode = bones.find(channel->_name);

		if(bonenode == bones.end()) {
			D_ERROR_FN(Locale::get("ERROR_BONE_FIND"),channel->_name.c_str());
			continue;
		}

		// ******** Position *****
		aiVector3D presentPosition( 0, 0, 0);
		if( channel->_positionKeys.size() > 0){
			// Look for present frame number. Search from last position if time is after the last time, else from beginning
			// Should be much quicker than always looking from start for the average use case.
			U32 frame = (time >= _lastTime) ? _lastPositions[a].x: 0;
			while( frame < channel->_positionKeys.size() - 1){
				if( time < channel->_positionKeys[frame+1].mTime){
					break;
				}
				frame++;
			}

			// interpolate between this frame's value and next frame's value
			U32 nextFrame = (frame + 1) % channel->_positionKeys.size();

			const aiVectorKey& key = channel->_positionKeys[frame];
			const aiVectorKey& nextKey = channel->_positionKeys[nextFrame];
			D32 diffTime = nextKey.mTime - key.mTime;
			if( diffTime < 0.0)
				diffTime += _duration;
			if( diffTime > 0) {
				F32 factor = F32( (time - key.mTime) / diffTime);
				presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
			} else {
				presentPosition = key.mValue;
			}
			_lastPositions[a].x = frame;
		}
		// ******** Rotation *********
		aiQuaternion presentRotation( 1, 0, 0, 0);
		if( channel->_rotationKeys.size() > 0)
		{
			U32 frame = (time >= _lastTime) ? _lastPositions[a].y : 0;
			while( frame < channel->_rotationKeys.size()  - 1){
				if( time < channel->_rotationKeys[frame+1].mTime)
					break;
				frame++;
			}

			// interpolate between this frame's value and next frame's value
			U32 nextFrame = (frame + 1) % channel->_rotationKeys.size() ;

			const aiQuatKey& key = channel->_rotationKeys[frame];
			const aiQuatKey& nextKey = channel->_rotationKeys[nextFrame];
			D32 diffTime = nextKey.mTime - key.mTime;
			if( diffTime < 0.0) diffTime += _duration;
			if( diffTime > 0) {
				F32 factor = F32( (time - key.mTime) / diffTime);
				aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
			} else presentRotation = key.mValue;
			_lastPositions[a].y = frame;
		}

		// ******** Scaling **********
		aiVector3D presentScaling( 1, 1, 1);
		if( channel->_scalingKeys.size() > 0) {
			U32 frame = (time >= _lastTime) ? _lastPositions[a].z : 0;
			while( frame < channel->_scalingKeys.size() - 1){
				if( time < channel->_scalingKeys[frame+1].mTime)
					break;
				frame++;
			}

			presentScaling = channel->_scalingKeys[frame].mValue;
			_lastPositions[a].z = frame;
		}

		aiMatrix4x4 mat = aiMatrix4x4( presentRotation.GetMatrix());

		mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
		mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
		mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
		mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
		if(GFX_DEVICE.getApi() == Direct3D){
			mat.Transpose();
		}

		bonenode->second->_localTransform = mat;
	}
	_lastTime = time;
}

};

Commits for Divide-Framework/trunk/Source Code/Geometry/Animations/AnimationEvaluator.cpp

Diff revisions: vs.
Revision Author Commited Message
334 Diff Diff IonutCava picture IonutCava Wed 10 Dec, 2014 17:21:22 +0000

[Ionut]
- Reorganized the Hardware project and renamed to "Platform"
- Reorganized the Server project

333 Diff Diff IonutCava picture IonutCava Tue 09 Dec, 2014 16:15:44 +0000

[Ionut]
- Removed “core.h” and moved everything to their appropriate header files
- Renamed MathClasses to MathMatrices (finally)
- Renamed “-Inl.h” files to ".inl"
- Some String wrapper refactoring
- Update “InstallLibraries.bat” so that it still offers valid options

326 Diff Diff IonutCava picture IonutCava Tue 30 Sep, 2014 21:11:32 +0000

[Ionut]
- Fixed more memory leaks
- Simplified Task interface and timing System
- Improved compatibility between Boost, STL and EASTL with random combinations of vectors, strings and maps
- Simplified Light class by removing the “slot” member
- Random optimizations

321 Diff Diff IonutCava picture IonutCava Wed 03 Sep, 2014 22:05:15 +0000

[Ionut]
- Added support (and enabled by default) for the EASTL library (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html / https://github.com/paulhodge/EASTL)
— Strings, vectors and hash_maps can be combined from EASTL, STL and Boost (not all combinations work. e.g. EASTL strings with STL/Boost containers due to the lack of a proper hash function)

318 Diff Diff IonutCava picture IonutCava Sat 30 Aug, 2014 17:35:53 +0000

[Ionut]
- Wrapped the entire code in a “Divide” namespace
- VertexBuffers now call “shrink_to_fit” on all internal data storage
- Improved some vector performance by preferring “emplace_back” instead of “push_back” + proepr usage of reserve / resize
- Wrapped OIS specific types and classes in Divide::Input namespace
- Added the messageBox.layout file (forgot it in the previous few commits)

274 Diff Diff IonutCava picture IonutCava Fri 13 Jun, 2014 12:56:03 +0000

[Ionut] [[BR]]
- Simplified buffer based rendering (VertexBuffer & GenericVertexData are now exclusively command based) [[BR]]
- Update bone buffer to persistent mapped-SSBO system with double-buffering [[BR]]
- Simplified sky rendering and (finally) reduced the sun’s radius [[BR]]

270 Diff Diff IonutCava picture IonutCava Thu 05 Jun, 2014 19:08:07 +0000

[Ionut][[BR]]
- SubMeshes now use a single vertex buffer (owned by the parent mesh) with proper offsetting and querying [[BR]]
— Implementation not optimal yet [[BR]]
- Cleaned up VertexBuffer related classes [[BR]]

260 Diff Diff k1ngp1n picture k1ngp1n Sat 03 May, 2014 19:33:41 +0000

[Ionut] [[BR]]
- More work on CSM. Reverted back to VSM to allow easier blurring and filtering [[BR]]
- Rewrote FrameBuffer classes to fix MSAA and memory leaks that occurred on resize (double creation of textures) [[BR]]
— Removed FBType. FrameBuffer types depend only on attachment types and if it’s MSAA enabled or not [[BR]]
- Rewrote RenderState classes to be API agnostic [[BR]]
- Bug fixes in math classes [[BR]]
- Changed “resolution change” logic [[BR]]
- Simplified some options in config.xml [[BR]]
- Improved per-light shadow options [[BR]]

221 Diff Diff k1ngp1n picture k1ngp1n Wed 08 Jan, 2014 18:50:02 +0000

[Ionut] [[BR]]
- Merged branch “Shadows And Animations” back into trunk [[BR]]
- Added DoxygenGUI project file [[BR]]

  • Buggy *
186 k1ngp1n picture k1ngp1n Sun 24 Nov, 2013 19:14:54 +0000

[Ionut] [[BR]]
- Increased precision of internal timers (delta time stored as double and computed by the kernel) [[BR]]
- Some thread sync fixes [[BR]]
- More work on the profile timers. Added a main loop timer as an example (Kernel.cpp -> mainLoopApp) [[BR]]
- Physics update <-> SceneGraphNode transform update sync (rather primitive, but it works) [[BR]]
— Setting a position or rotation manually was overridden by the physics engine. Now, manual transform updates have a higher priority [[BR]]