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
203
204
205
206
#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)
    : FrameListener(),
      _type(type),
      _moveSpeed(Metric::Base(1.0f)),
      _acceleration(Metric::Base(1.0f)),
      _moveTolerance(0.1f),
      _prevTime(0)
{
    REGISTER_FRAME_LISTENER(this, 5);
}

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

void Unit::setParentNode(SceneGraphNode_ptr node) {
    _node = node;
    _currentPosition = _node.lock()->get<PhysicsComponent>()->getPosition();
}

/// 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();
    }
    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();
    }
    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();
    }
    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
827 Diff Diff IonutCava picture IonutCava Sun 22 Jan, 2017 21:59:36 +0000

[IonutCava]
- ShaderBuffers now decide heuristically if they get persistently mapped or not (depends on size. Current limit is 512Kb for subData calls.
- Separate visible node command generation into 2 steps: onRender and getDrawPackage. onRender allows the creation of parallel tasks that should finish by the time the second call, getDrawPackage reaches the same node
- Update ParticleEmitter to take into account multiple players and increase parallelism at the cost of memory consumption and complexity.
- Add a default bounding box for Players (add extents to SceneTransform nodes)
- All buffers (ShaderBuffer, d3dConstantBuffer, glUniformBuffer, glBufferImpl, glGenericBuffer, etc) use BufferParams for creation.
— Constructor and create calls have been merged together

818 Diff Diff IonutCava picture IonutCava Mon 16 Jan, 2017 17:23:20 +0000

[IonutCava]
- Units get their bound node setup by the SGN UnitComponent and not during creation
- Profile guided optimizations

817 Diff Diff IonutCava picture IonutCava Sun 15 Jan, 2017 21:29:59 +0000

[IonutCava]
- Add a new Unit component to SGNs that holds NPC/Player/etc. objects
- Add support for multiple keyboard+mouse combos and joysticks and add mapping between these and players

813 Diff Diff IonutCava picture IonutCava Thu 12 Jan, 2017 17:18:55 +0000

[IonutCava]
- Initial split screen support:
— Add support for multiple Player objects per scene
— Compute viewport alignment for every player
— Render scene once for every viewport
- ToDo:
— Bind each player to an input method
— Add per-player camera
— Per player render pass: set player camera as default camera

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 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