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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include "Headers/Unit.h"
#include "Graphs/Headers/SceneGraphNode.h"
#include "Core/Time/Headers/ApplicationTimer.h"
#include "Core/Math/Headers/Transform.h"
#include "Managers/Headers/FrameListenerManager.h"

namespace Divide {

Unit::Unit(UnitType type, SceneGraphNode_ptr node)
    : FrameListener(),
      _type(type),
      _node(node),
      _moveSpeed(Metric::Base(1.0f)),
      _acceleration(Metric::Base(1.0f)),
      _moveTolerance(0.1f),
      _prevTime(0)
{
    REGISTER_FRAME_LISTENER(this, 5);
    _currentPosition =
        _node.lock()->get<PhysicsComponent>()->getPosition();
}

Unit::~Unit()
{ 
    UNREGISTER_FRAME_LISTENER(this);
}


/// Pathfinding, collision detection, animation playback should all be
/// controlled from here
bool Unit::moveTo(const vec3<F32>& targetPosition) {
    // We should always have a node
    SceneGraphNode_ptr sgn = _node.lock();
    if (!sgn) {
        return false;
    }
    WriteLock w_lock(_unitUpdateMutex);
    // We receive move request every frame for now (or every task tick)
    // Start plotting a course from our current position
    _currentPosition = sgn->get<PhysicsComponent>()->getPosition();
    _currentTargetPosition = targetPosition;

    if (_prevTime <= 0) {
        _prevTime = Time::ElapsedMilliseconds();
    }
    // get current time in ms
    D64 currentTime = Time::ElapsedMilliseconds();
    // figure out how many milliseconds have elapsed since last move time
    D64 timeDif = currentTime - _prevTime;
    CLAMP<D64>(timeDif, 0, timeDif);
    // update previous time
    _prevTime = currentTime;
    // 'moveSpeed' m/s = '0.001 * moveSpeed' m / ms
    // distance = timeDif * 0.001 * moveSpeed
    F32 moveDistance = std::min(to_float(_moveSpeed * (Time::MillisecondsToSeconds(timeDif))),
                                0.0f);

    bool returnValue = IS_TOLERANCE(moveDistance, Metric::Centi(1.0f));

    if (!returnValue) {
        F32 xDelta = _currentTargetPosition.x - _currentPosition.x;
        F32 yDelta = _currentTargetPosition.y - _currentPosition.y;
        F32 zDelta = _currentTargetPosition.z - _currentPosition.z;
        bool xTolerance = IS_TOLERANCE(xDelta, _moveTolerance);
        bool yTolerance = IS_TOLERANCE(yDelta, _moveTolerance);
        bool zTolerance = IS_TOLERANCE(zDelta, _moveTolerance);

        // Compute the destination point for current frame step
        vec3<F32> interpPosition;
        if (!yTolerance && !IS_ZERO(yDelta)) {
            interpPosition.y =
                (_currentPosition.y > _currentTargetPosition.y ? -moveDistance
                                                               : moveDistance);
        }
        if ((!xTolerance || !zTolerance)) {
            // Update target
            if (IS_ZERO(xDelta)) {
                interpPosition.z =
                    (_currentPosition.z > _currentTargetPosition.z
                         ? -moveDistance
                         : moveDistance);
            } else if (IS_ZERO(zDelta)) {
                interpPosition.x =
                    (_currentPosition.x > _currentTargetPosition.x
                         ? -moveDistance
                         : moveDistance);
            } else if (std::fabs(xDelta) > std::fabs(zDelta)) {
                F32 value = std::fabs(zDelta / xDelta) * moveDistance;
                interpPosition.z =
                    (_currentPosition.z > _currentTargetPosition.z ? -value
                                                                   : value);
                interpPosition.x =
                    (_currentPosition.x > _currentTargetPosition.x
                         ? -moveDistance
                         : moveDistance);
            } else {
                F32 value = std::fabs(xDelta / zDelta) * moveDistance;
                interpPosition.x =
                    (_currentPosition.x > _currentTargetPosition.x ? -value
                                                                   : value);
                interpPosition.z =
                    (_currentPosition.z > _currentTargetPosition.z
                         ? -moveDistance
                         : moveDistance);
            }
            // commit transformations
            sgn->get<PhysicsComponent>()->translate(interpPosition);
        }
    }

    return returnValue;
}

/// Move along the X axis
bool Unit::moveToX(const F32 targetPosition) {
    SceneGraphNode_ptr sgn = _node.lock();
    if (!sgn) {
        return false;
    }
    /// Update current position
    WriteLock w_lock(_unitUpdateMutex);
    _currentPosition = sgn->get<PhysicsComponent>()->getPosition();
    w_lock.unlock();
    return moveTo(vec3<F32>(targetPosition,
                            _currentPosition.y,
                            _currentPosition.z));
}

/// Move along the Y axis
bool Unit::moveToY(const F32 targetPosition) {
    SceneGraphNode_ptr sgn = _node.lock();
    if (!sgn) {
        return false;
    }
    /// Update current position
    WriteLock w_lock(_unitUpdateMutex);
    _currentPosition = sgn->get<PhysicsComponent>()->getPosition();
    w_lock.unlock();
    return moveTo(vec3<F32>(_currentPosition.x,
                            targetPosition,
                            _currentPosition.z));
}

/// Move along the Z axis
bool Unit::moveToZ(const F32 targetPosition) {
    SceneGraphNode_ptr sgn = _node.lock();
    if (!sgn) {
        return false;
    }
    /// Update current position
    WriteLock w_lock(_unitUpdateMutex);
    _currentPosition = sgn->get<PhysicsComponent>()->getPosition();
    w_lock.unlock();
    return moveTo(vec3<F32>(_currentPosition.x,
                            _currentPosition.y,
                            targetPosition));
}

/// Further improvements may imply a cooldown and collision detection at
/// destination (thus the if-check at the end)
bool Unit::teleportTo(const vec3<F32>& targetPosition) {
    SceneGraphNode_ptr sgn = _node.lock();
    if (!sgn) {
        return false;
    }
    WriteLock w_lock(_unitUpdateMutex);
    /// We receive move request every frame for now (or every task tick)
    /// Check if the current request is already processed
    if (!_currentTargetPosition.compare(targetPosition, 0.00001f)) {
        /// Update target
        _currentTargetPosition = targetPosition;
    }
    PhysicsComponent* nodePhysicsComponent =
        sgn->get<PhysicsComponent>();
    /// Start plotting a course from our current position
    _currentPosition = nodePhysicsComponent->getPosition();
    /// teleport to desired position
    nodePhysicsComponent->setPosition(_currentTargetPosition);
    /// Update current position
    _currentPosition = nodePhysicsComponent->getPosition();
    /// And check if we arrived
    if (_currentTargetPosition.compare(_currentPosition, 0.0001f)) {
        return true;  ///< yes
    }

    return false;  ///< no
}

void Unit::setAttribute(U32 attributeID, I32 initialValue) {
    _attributes[attributeID] = initialValue;
}

I32 Unit::getAttribute(U32 attributeID) const {
    AttributeMap::const_iterator it = _attributes.find(attributeID);
    if (it != std::end(_attributes)) {
        return it->second;
    }

    return -1;
}

};

Commits for Divide-Framework/trunk/Source Code/Dynamics/Entities/Units/Unit.cpp

Diff revisions: vs.
Revision Author Commited Message
693 Diff Diff IonutCava picture IonutCava Thu 28 Apr, 2016 16:19:35 +0000

[IonutCava]
- Cleanup Time and Profiling code

680 Diff Diff IonutCava picture IonutCava Thu 14 Apr, 2016 16:15:38 +0000

[IonutCava]
- Added a mat2 class (untested)
- Added static asserts to matrices, vectors and quaternions to allow only arithmetic (sans bool) data types
- Added more vector unit tests
- Added unit tests for matrices
- D32 finally renamed to D64 as the VC++ compiler is considered as the reference compiler

648 Diff Diff IonutCava picture IonutCava Sun 21 Feb, 2016 16:32:52 +0000

[IonutCava]
- Update copyright notice
- Move BoundingBox and BoundingSphere to a new BoundsComponent
— Add a temp hack in SceneGraphNode to update these

444 Diff Diff IonutCava picture IonutCava Thu 21 May, 2015 16:06:53 +0000

[Ionut]
- More platform independent code cleanup:
— Moved platform specific defines to their respective header files (e.g. THREAD_LOCAL)
— Moved most preprocessor defines from the VisualC++ projects into source code
— Removed compiler specific code (e.g. warning disables) and fixed most warning resulting from this

442 Diff Diff IonutCava picture IonutCava Wed 20 May, 2015 15:25:02 +0000

[Ionut]
- Better platform handling:
— All platform specific code moved in 3 separate files: PlatformDefinesWindows / PlatformDefinesUnix / PlatformDefinesApple
— Added CPU and RAM check at startup to make sure we meet minimum requirements to run properly
- Smart pointers should never used MemoryManager_NEW for allocating memory (MemoryManager_NEW tracks allocations but must be matched with a DELETE call in order to no report leaks). Corrected.
- Zombification of Singletons is only enabled in Debug builds
- Fixed a bug in Task.cpp (nowTime check) that prevented some tasks to run on the first call (changed a ‘>’ check to a ‘>=’)
— This also fixed bounding box computations for skinned submeshes
- Improved dead zone handling for joysticks

438 Diff Diff IonutCava picture IonutCava Fri 15 May, 2015 15:46:43 +0000

[Ionut]
- SceneGraphNodes are now stored as shared pointers and Units/AI entities reference them with std::weak_ptr
— ToDo: Make constructor/destructor private again. (made public as a temporary hack to make it work with std::shared_ptr)
- SceneGraphNode’s children map is now read/updated with proper locking mechanism to avoid threading issues (e.g. AI tries to delete a node and rendering thread tries to read material data from it at the same time)
- GL_API does not need to store the previous shader program, just the previous shader program handle.
— Previous responsibilities shifted to glShaderProgram

434 Diff Diff IonutCava picture IonutCava Wed 13 May, 2015 22:26:29 +0000

[Ionut]
- Simplified SceneGraph/SceneGraphNode classes:
— RAII style. Dropped load/unload
— SGN deletion callbacks are tracked by ID
— Better node deletion System
- Better scoring system with manual override:
— Key 1 adds a point to team A
— Key 2 adds a point to team B
- Safer scene pointer management in SceneManager

431 Diff Diff IonutCava picture IonutCava Tue 12 May, 2015 22:22:46 +0000

[Ionut]
- More WarScene AI work

423 Diff Diff IonutCava picture IonutCava Wed 06 May, 2015 15:45:24 +0000

[Ionut]
- WarScene AI work

422 IonutCava picture IonutCava Tue 05 May, 2015 20:33:47 +0000

[Ionut]
- Bug fixes for the previous commit
- Replace most static_cast<U32/I32> with to_int / to_uint