File: PatchSurface.cpp

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (110 lines) | stat: -rw-r--r-- 2,885 bytes parent folder | download | duplicates (3)
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
#include "PatchSurface.h"

#include <algorithm>

namespace model
{

namespace
{
    // Adapter method to convert patch vertices to MeshVertex type
    inline MeshVertex convertPatchVertex(const VertexNT& in)
    {
        // Colour will be set to 1,1,1 by the constructor
        return MeshVertex(in.vertex, in.normal, in.texcoord);
    }
}

PatchSurface::PatchSurface(const std::string& materialName, PatchMesh& mesh) :
    _materialName(materialName)
{
    assert(mesh.width >= 2 && mesh.height >= 2);

    _vertices.reserve(mesh.vertices.size());
    _indices.reserve((mesh.height - 1) * (mesh.width - 1) * 6); // 6 => 2 triangles per quad

    // Load all the vertices into the target vector
    std::transform(mesh.vertices.begin(), mesh.vertices.end(),
        std::back_inserter(_vertices), convertPatchVertex);

    _bounds = AABB();

    // Accumulate the bounds
    for (const auto& vertex : _vertices)
    {
        _bounds.includePoint(vertex);
    }

    // Generate the indices to define the triangles in clockwise order
    for (std::size_t h = 0; h < mesh.height - 1; ++h)
    {
        auto rowOffset = h * mesh.width;

        for (std::size_t w = 0; w < mesh.width - 1; ++w)
        {
            _indices.push_back(static_cast<unsigned int>(rowOffset + w + mesh.width));
            _indices.push_back(static_cast<unsigned int>(rowOffset + w + 1));
            _indices.push_back(static_cast<unsigned int>(rowOffset + w));

            _indices.push_back(static_cast<unsigned int>(rowOffset + w + mesh.width));
            _indices.push_back(static_cast<unsigned int>(rowOffset + w + mesh.width + 1));
            _indices.push_back(static_cast<unsigned int>(rowOffset + w + 1));
        }
    }
}

// Inherited via IIndexedModelSurface
int PatchSurface::getNumVertices() const
{
    return static_cast<int>(_vertices.size());
}

int PatchSurface::getNumTriangles() const
{
    return static_cast<int>(_indices.size() / 3); // 3 indices per triangle
}

const MeshVertex& PatchSurface::getVertex(int vertexNum) const
{
    return _vertices[vertexNum];
}

ModelPolygon PatchSurface::getPolygon(int polygonIndex) const
{
    assert(polygonIndex >= 0 && polygonIndex * 3 < static_cast<int>(_indices.size()));

    ModelPolygon poly;

    poly.a = _vertices[_indices[polygonIndex * 3]];
    poly.b = _vertices[_indices[polygonIndex * 3 + 1]];
    poly.c = _vertices[_indices[polygonIndex * 3 + 2]];

    return poly;
}

const std::string& PatchSurface::getDefaultMaterial() const
{
    return _materialName;
}

const std::string& PatchSurface::getActiveMaterial() const
{
    return _materialName;
}

const std::vector<MeshVertex>& PatchSurface::getVertexArray() const
{
    return _vertices;
}

const std::vector<unsigned int>& PatchSurface::getIndexArray() const
{
    return _indices;
}

const AABB& PatchSurface::getSurfaceBounds() const
{
    return _bounds;
}

}