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
#include "Headers/Frustum.h"
#include "Headers/Camera.h"

#include "Platform/Video/Headers/GFXDevice.h"
#include "Core/Math/BoundingVolumes/Headers/BoundingBox.h"

namespace Divide {

Frustum::Frustum(Camera& parentCamera)
    : _pointsDirty(true), _parentCamera(parentCamera) {}

Frustum::FrustCollision Frustum::ContainsPoint(const vec3<F32>& point) const {
    for (const Plane<F32>& frustumPlane : _frustumPlanes) {
        if (frustumPlane.classifyPoint(point) !=
            Plane<F32>::Side::POSITIVE_SIDE) {
            return FrustCollision::FRUSTUM_OUT;
        }
    }

    return FrustCollision::FRUSTUM_IN;
}

Frustum::FrustCollision Frustum::ContainsSphere(const vec3<F32>& center,
                                                F32 radius) const {
    F32 distance = 0.0f;

    for (const Plane<F32>& frustumPlane : _frustumPlanes) {
        distance = frustumPlane.signedDistanceToPoint(center);

        if (distance < -radius) {
            return FrustCollision::FRUSTUM_OUT;
        }

        if (std::fabs(distance) < radius) {
            return FrustCollision::FRUSTUM_INTERSECT;
        }
    }

    return FrustCollision::FRUSTUM_IN;
}

Frustum::FrustCollision Frustum::ContainsBoundingBox(const BoundingBox& bbox) const {
    //const vec3<F32>* box[] = {&bbox.getMin(), &bbox.getMax()};
    vec3<F32> vmin, vmax;
    vec3<F32> bmin = bbox.getMin();
    vec3<F32> bmax = bbox.getMax();
    FrustCollision ret = FrustCollision::FRUSTUM_IN;
    for (const Plane<F32>& frustumPlane : _frustumPlanes) {
        // p-vertex selection (with the index trick)
        // According to the plane normal we can know the
        // indices of the positive vertex
        const vec3<F32>& normal = frustumPlane.getNormal();
        /*const I32 px = static_cast<I32>(p.x < 0.0f);
        const I32 py = static_cast<I32>(p.y < 0.0f);
        const I32 pz = static_cast<I32>(p.z < 0.0f);

        vmin.set(box[1 - px]->x, box[1 - py]->y, box[1 - pz]->z);
        vmax.set(box[px]->x, box[py]->y, box[pz]->z);*/


        if (frustumPlane.signedDistanceToPoint(bbox.getPVertex(normal)) < 0) {
            return FrustCollision::FRUSTUM_OUT;
        }

        if (frustumPlane.signedDistanceToPoint(bbox.getNVertex(normal)) < 0) {
            ret = FrustCollision::FRUSTUM_INTERSECT;
        }
    }

    return ret;
}

void Frustum::Extract(const mat4<F32>& viewMatrix, const mat4<F32>& projectionMatrix) {
    mat4<F32>::Multiply(viewMatrix, projectionMatrix, _viewProjectionMatrixCache);

    Plane<F32>& rightPlane = _frustumPlanes[0];
    Plane<F32>& leftPlane = _frustumPlanes[1];
    Plane<F32>& bottomPlane = _frustumPlanes[2];
    Plane<F32>& topPlane = _frustumPlanes[3];
    Plane<F32>& farPlane = _frustumPlanes[4];
    Plane<F32>& nearPlane = _frustumPlanes[5];

    const F32* mat = &_viewProjectionMatrixCache.mat[0];

    rightPlane.set(mat[3] - mat[0], mat[7] - mat[4], mat[11] - mat[8], mat[15] - mat[12]);
    rightPlane.normalize();

    leftPlane.set(mat[3] + mat[0], mat[7] + mat[4], mat[11] + mat[8], mat[15] + mat[12]);
    leftPlane.normalize();

    bottomPlane.set(mat[3] + mat[1], mat[7] + mat[5], mat[11] + mat[9], mat[15] + mat[13]);
    bottomPlane.normalize();

    topPlane.set(mat[3] - mat[1], mat[7] - mat[5], mat[11] - mat[9], mat[15] - mat[13]);
    topPlane.normalize();

    farPlane.set(mat[3] - mat[2], mat[7] - mat[6], mat[11] - mat[10], mat[15] - mat[14]);
    farPlane.normalize();

    nearPlane.set(mat[3] + mat[2], mat[7] + mat[6], mat[11] + mat[10], mat[15] + mat[14]);
    nearPlane.normalize();

    _pointsDirty = true;
}

void Frustum::intersectionPoint(const Plane<F32>& a, const Plane<F32>& b,
                                const Plane<F32>& c, vec3<F32>& outResult) {
    outResult.set((a.getDistance() * (Cross(b.getNormal(), c.getNormal()))) +
                  (b.getDistance() * (Cross(c.getNormal(), a.getNormal()))) +
                  (c.getDistance() * (Cross(a.getNormal(), b.getNormal()))) /
                  -Dot(a.getNormal(), Cross(b.getNormal(), c.getNormal())));
}

void Frustum::updatePoints() {
    if (!_pointsDirty) {
        return;
    }

    const Plane<F32>& rightPlane = _frustumPlanes[0];
    const Plane<F32>& leftPlane = _frustumPlanes[1];
    const Plane<F32>& bottomPlane = _frustumPlanes[2];
    const Plane<F32>& topPlane = _frustumPlanes[3];
    const Plane<F32>& farPlane = _frustumPlanes[4];
    const Plane<F32>& nearPlane = _frustumPlanes[5];

    intersectionPoint(nearPlane, leftPlane, topPlane, _frustumPoints[0]);
    intersectionPoint(nearPlane, rightPlane, topPlane, _frustumPoints[1]);
    intersectionPoint(nearPlane, rightPlane, bottomPlane, _frustumPoints[2]);
    intersectionPoint(nearPlane, leftPlane, bottomPlane, _frustumPoints[3]);
    intersectionPoint(farPlane, leftPlane, topPlane, _frustumPoints[4]);
    intersectionPoint(farPlane, rightPlane, topPlane, _frustumPoints[5]);
    intersectionPoint(farPlane, rightPlane, bottomPlane, _frustumPoints[6]);
    intersectionPoint(farPlane, leftPlane, bottomPlane, _frustumPoints[7]);

    _pointsDirty = false;
}

// Get the frustum corners in WorldSpace. cornerWS must be a vector with at
// least 8 allocated slots
void Frustum::getCornersWorldSpace(vectorImpl<vec3<F32> >& cornersWS) {
    assert(cornersWS.size() >= 8);

    updatePoints();

    for (U8 i = 0; i < 8; ++i) {
        cornersWS[i].set(_frustumPoints[i]);
    }
}

// Get the frustum corners in ViewSpace. cornerVS must be a vector with at least
// 8 allocated slots
void Frustum::getCornersViewSpace(vectorImpl<vec3<F32> >& cornersVS) {
    assert(cornersVS.size() >= 8);

    updatePoints();

    const mat4<F32>& viewMatrix = _parentCamera.getViewMatrix();
    for (U8 i = 0; i < 8; ++i) {
        cornersVS[i].set(viewMatrix.transformHomogeneous(_frustumPoints[i]));
    }
}
};

Commits for Divide-Framework/trunk/Source Code/Rendering/Camera/Frustum.cpp

Diff revisions: vs.
Revision Author Commited Message
781 Diff Diff IonutCava picture IonutCava Wed 12 Oct, 2016 16:03:46 +0000

[IonutCava]
- ShaderComputeQueue <-> Material shader request bug fix (element stuck in QUEUED state)
- More Camera class cleanups
- Add a method of removing EnvironmentProbes from their Pool

779 Diff Diff IonutCava picture IonutCava Mon 10 Oct, 2016 15:31:45 +0000

[IonutCava]
- Frustum calculation bug fix

720 Diff Diff IonutCava picture IonutCava Mon 06 Jun, 2016 15:51:06 +0000

[IonutCava]
- PVS-Studio guided static analysis fixes and optimizations
- Added a flag to SceneState to bypass the Save/Load system not needed for certain types of scenes (menus, cinematics, etc)

646 Diff Diff IonutCava picture IonutCava Tue 16 Feb, 2016 16:33:15 +0000

[IonutCava]
- Improved frustum culling performance:
— Use p & n-vertex checks
— Pass max distance from RenderPassCuller
- Add GEQUAL / LEQUAL checks that work for F32 and D32 types

640 Diff Diff IonutCava picture IonutCava Tue 09 Feb, 2016 17:18:17 +0000

[IonutCava]
- More Octree updates
- Fixed bounding box collision check
- Added initial intersection code
- Added on-demand flush call for fence locking system

587 Diff Diff IonutCava picture IonutCava Fri 27 Nov, 2015 17:00:25 +0000

[IonutCava]
- Finished multi-light rendering:
— Proper position/distance transform (homogeneous trans for positions / non-homogeneous trans for directions)
-— Point lights with range based attenuation
-— Spot lights with inner and outer cones for smooth falloff
-— Directional lights same as before
- Added a basic Flashlight system: spot light at the camera’s position facing forward (toggled with L key)
- WarScene updated:
— 16 point lights moving around the scene with random colours

543 Diff Diff IonutCava picture IonutCava Fri 30 Oct, 2015 17:18:18 +0000

[IonutCava]
- More profile guided optimizations
- Attempt to render all CSM splits in a single pass using geometry shader based instancing (unfinished)

433 Diff Diff IonutCava picture IonutCava Wed 13 May, 2015 15:57:17 +0000

[Ionut]
- Some code cleanup (global functions now start with a capital case)
- Some fixed timestep adjustments
- Input logging (key presses & mouse button presses with location at event time)

420 Diff Diff IonutCava picture IonutCava Mon 04 May, 2015 16:30:23 +0000

[Ionut]
- Bug fixes:
— Upload bone buffers for every rendering stage (not just display). Solves bad shadow pass skinning when the node hasn’t entered the display pass view frustum yet
— Fix translucency check logic in Material and avoid creating an opacity map if it uses the same texture as the albedo map. Transparency will be automatically picked up from the albedo map. Solves transparent materials not discarding the needed pixels.
— Fix camera world matrix retrieval. Solves bad shadow camera computations if the main scene camera isn’t wasn’t moved often.
— Removed DSA_EXT texture update methods and replaced them with normal bind->edit methods. DSA_EXT is still buggy on AMD with Catalyst 15.4b

390 IonutCava picture IonutCava Thu 26 Mar, 2015 22:41:09 +0000

[Ionut]
- Renamed most enum values to shorter names (possible due to enum-class type safety)
- Removed to redundant state change cases (glCullFace when CULL_MODE_NONE was used, and glLineWidth that didn’t have redundancy checks)
- Added a hacky SceneGraphNode render call count to skip the first 3 draw calls so that the data buffers have time to update properly (solves flickering and erroneous rendering when moving camera to include a new node)