, but only one primitive per
size_t numPrimitives = pNumPrimitives;
- if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
+ if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) {
numPrimitives = 1;
+ }
+
// For continued primitives, the given count is actually the number of
's inside the parent tag
if (pPrimType == Prim_TriStrips) {
size_t numberOfVertices = indices.size() / numOffsets;
@@ -2166,15 +2182,15 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
}
// how many parameters to read per transformation type
- static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
+ static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
std::string value;
XmlParser::getValueAsString(node, value);
const char *content = value.c_str();
-
+ const char *end = value.c_str() + value.size();
// read as many parameters and store in the transformation
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
// skip whitespace before the number
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
// read a number
content = fast_atoreal_move(content, tf.f[a]);
}
diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp
index f69cdfce2..0f3da2626 100644
--- a/code/AssetLib/DXF/DXFLoader.cpp
+++ b/code/AssetLib/DXF/DXFLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the DXF importer class
*/
-
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
#include "AssetLib/DXF/DXFLoader.h"
@@ -68,25 +67,267 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
// default vertex color that all uncolored vertices will receive
static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
-// color indices for DXF - 16 are supported, the table is
-// taken directly from the DXF spec.
-static const aiColor4D g_aclrDxfIndexColors[] = {
- aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
- aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
- aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
- aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
- aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
- aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
- aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
- aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
- aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
- aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
- aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
- aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
- aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
- aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
- aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
- aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
+// color indices for DXF - 256 are supported, the table is
+// taken directly from the AutoCad Index (ACI) table
+// https://gohtx.com/acadcolors.php
+//STH 2024-0126
+static const aiColor4D g_aclrDxfIndexColors[256] = {
+ aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0
+ aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1
+ aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2
+ aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3
+ aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4
+ aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5
+ aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6
+ aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7
+ aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8
+ aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9
+ aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11
+ aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12
+ aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13
+ aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14
+ aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15
+ aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17
+ aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19
+ aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21
+ aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22
+ aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23
+ aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24
+ aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25
+ aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27
+ aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29
+ aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30
+ aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31
+ aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32
+ aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33
+ aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34
+ aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35
+ aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37
+ aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39
+ aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40
+ aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41
+ aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43
+ aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45
+ aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47
+ aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49
+ aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50
+ aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51
+ aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53
+ aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55
+ aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57
+ aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59
+ aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60
+ aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61
+ aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63
+ aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65
+ aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67
+ aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69
+ aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70
+ aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71
+ aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72
+ aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73
+ aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74
+ aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75
+ aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77
+ aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79
+ aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81
+ aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82
+ aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83
+ aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84
+ aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85
+ aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87
+ aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89
+ aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91
+ aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92
+ aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93
+ aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94
+ aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95
+ aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97
+ aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99
+ aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101
+ aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102
+ aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103
+ aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104
+ aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105
+ aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107
+ aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109
+ aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110
+ aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111
+ aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112
+ aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113
+ aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114
+ aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115
+ aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117
+ aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119
+ aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120
+ aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121
+ aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123
+ aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125
+ aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127
+ aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129
+ aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130
+ aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131
+ aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133
+ aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135
+ aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137
+ aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139
+ aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140
+ aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141
+ aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143
+ aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145
+ aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147
+ aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149
+ aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150
+ aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151
+ aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152
+ aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153
+ aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154
+ aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155
+ aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157
+ aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159
+ aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161
+ aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162
+ aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163
+ aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164
+ aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165
+ aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167
+ aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169
+ aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171
+ aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172
+ aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173
+ aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174
+ aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175
+ aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177
+ aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179
+ aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181
+ aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182
+ aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183
+ aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184
+ aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185
+ aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187
+ aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189
+ aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190
+ aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191
+ aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192
+ aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193
+ aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194
+ aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195
+ aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197
+ aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199
+ aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200
+ aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201
+ aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203
+ aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205
+ aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207
+ aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209
+ aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210
+ aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211
+ aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213
+ aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215
+ aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217
+ aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219
+ aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220
+ aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221
+ aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223
+ aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225
+ aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227
+ aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229
+ aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230
+ aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231
+ aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232
+ aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233
+ aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234
+ aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235
+ aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237
+ aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239
+ aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241
+ aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242
+ aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243
+ aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244
+ aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245
+ aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247
+ aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249
+ aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250
+ aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251
+ aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252
+ aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253
+ aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254
+ aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255
};
#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
@@ -372,8 +613,12 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX order
aiMatrix4x4 trafo, tmp;
aiMatrix4x4::Translation(-bl_src.base,trafo);
- trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+ //Need to translate position before scaling the insert
+ //otherwise the position ends up being the position*scaling
+ //STH 2024.01.17
trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
+ trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+ //trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
// XXX rotation currently ignored - I didn't find an appropriate sample model.
if (insert.angle != 0.f) {
diff --git a/code/AssetLib/FBX/FBXExporter.cpp b/code/AssetLib/FBX/FBXExporter.cpp
index 28299544a..873179f4c 100644
--- a/code/AssetLib/FBX/FBXExporter.cpp
+++ b/code/AssetLib/FBX/FBXExporter.cpp
@@ -1807,7 +1807,7 @@ void FBXExporter::WriteObjects ()
p.AddP70numberA("DeformPercent", 0.0);
sdnode.AddChild(p);
// TODO: Normally just one weight per channel, adding stub for later development
- std::vectorfFullWeights;
+ std::vectorfFullWeights;
fFullWeights.push_back(100.);
sdnode.AddChild("FullWeights", fFullWeights);
sdnode.Dump(outstream, binary, indent);
diff --git a/code/AssetLib/Irr/IRRMeshLoader.cpp b/code/AssetLib/Irr/IRRMeshLoader.cpp
index b35a95c12..4a2f70882 100644
--- a/code/AssetLib/Irr/IRRMeshLoader.cpp
+++ b/code/AssetLib/Irr/IRRMeshLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -69,14 +69,6 @@ static constexpr aiImporterDesc desc = {
"xml irrmesh"
};
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IRRMeshImporter::IRRMeshImporter() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IRRMeshImporter::~IRRMeshImporter() = default;
-
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -116,8 +108,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
std::unique_ptr file(pIOHandler->Open(pFile));
// Check whether we can read from the file
- if (file == nullptr)
+ if (file == nullptr) {
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
+ }
// Construct the irrXML parser
XmlParser parser;
@@ -148,13 +141,11 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
bool useColors = false;
- /*
- ** irrmesh files have a top level owning multiple nodes.
- ** Each contains , , and
- ** tags here directly owns the material data specs
- ** are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
- ** is ignored, I think assimp recalculates those?
- */
+ // irrmesh files have a top level owning multiple nodes.
+ // Each contains , , and
+ // tags here directly owns the material data specs
+ // are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
+ // is ignored, I think assimp recalculates those?
// Parse the XML file
pugi::xml_node const &meshNode = root.child("mesh");
@@ -201,7 +192,6 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
releaseMaterial(&curMat);
- // releaseMesh(&curMesh);
continue; // Bail out early
};
@@ -250,7 +240,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
};
// We know what format buffer is, collect numbers
- ParseBufferVertices(verticesNode.text().get(), vertexFormat,
+ std::string v = verticesNode.text().get();
+ const char *end = v.c_str() + v.size();
+ ParseBufferVertices(v.c_str(), end, vertexFormat,
curVertices, curNormals,
curTangents, curBitangents,
curUVs, curUV2s, curColors, useColors);
@@ -329,8 +321,10 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// NOTE this might explode for UTF-16 and wchars
const char *sz = indicesNode.text().get();
+ const char *end = sz + std::strlen(sz);
+
// For each index loop over aiMesh faces
- while (SkipSpacesAndLineEnd(&sz)) {
+ while (SkipSpacesAndLineEnd(&sz, end)) {
if (curFace >= faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
break;
@@ -354,12 +348,18 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// Copy over data to aiMesh
*pcV++ = curVertices[idx];
- if (pcN) *pcN++ = curNormals[idx];
- if (pcT) *pcT++ = curTangents[idx];
- if (pcB) *pcB++ = curBitangents[idx];
- if (pcC0) *pcC0++ = curColors[idx];
- if (pcT0) *pcT0++ = curUVs[idx];
- if (pcT1) *pcT1++ = curUV2s[idx];
+ if (pcN)
+ *pcN++ = curNormals[idx];
+ if (pcT)
+ *pcT++ = curTangents[idx];
+ if (pcB)
+ *pcB++ = curBitangents[idx];
+ if (pcC0)
+ *pcC0++ = curColors[idx];
+ if (pcT0)
+ *pcT0++ = curUVs[idx];
+ if (pcT1)
+ *pcT1++ = curUV2s[idx];
// start new face
if (++curIdx == 3) {
@@ -368,8 +368,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
}
}
// We should be at the end of mFaces
- if (curFace != faceEnd)
+ if (curFace != faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
+ }
}
// Finish processing the mesh - do some small material workarounds
@@ -379,8 +380,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
aiMaterial *mat = (aiMaterial *)curMat;
mat->AddProperty(&curColors[0].a, 1, AI_MATKEY_OPACITY);
}
- // textMeaning = 2;
-
+
// end of previous buffer. A material and a mesh should be there
if (!curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
@@ -421,37 +421,37 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
};
}
-void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
+void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
std::vector &vertices, std::vector &normals,
std::vector &tangents, std::vector &bitangents,
std::vector &UVs, std::vector &UV2s,
std::vector &colors, bool &useColors) {
// read vertices
do {
- SkipSpacesAndLineEnd(&sz);
+ SkipSpacesAndLineEnd(&sz, end);
aiVector3D temp;
aiColor4D c;
// Read the vertex position
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.z);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
vertices.push_back(temp);
// Read the vertex normals
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.z);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
normals.push_back(temp);
// read the vertex colors
@@ -463,14 +463,14 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
useColors = true;
colors.push_back(c);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
// read the first UV coordinate set
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
temp.z = 0.f;
temp.y = 1.f - temp.y; // DX to OGL
UVs.push_back(temp);
@@ -480,7 +480,7 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
// read the (optional) second UV coordinate set
if (vertexFormat == VertexFormat::t2coord) {
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
temp.y = 1.f - temp.y; // DX to OGL
@@ -490,33 +490,32 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
else if (vertexFormat == VertexFormat::tangent) {
// tangents
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.z);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
temp.y *= -1.0f;
tangents.push_back(temp);
// bitangents
sz = fast_atoreal_move(sz, (float &)temp.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.z);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
sz = fast_atoreal_move(sz, (float &)temp.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
temp.y *= -1.0f;
bitangents.push_back(temp);
}
- } while (SkipLine(&sz));
- /* IMPORTANT: We assume that each vertex is specified in one
- line. So we can skip the rest of the line - unknown vertex
- elements are ignored.
- */
+ } while (SkipLine(&sz, end));
+ // IMPORTANT: We assume that each vertex is specified in one
+ // line. So we can skip the rest of the line - unknown vertex
+ // elements are ignored.
}
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
diff --git a/code/AssetLib/Irr/IRRMeshLoader.h b/code/AssetLib/Irr/IRRMeshLoader.h
index 620e40dba..4ab3615ee 100644
--- a/code/AssetLib/Irr/IRRMeshLoader.h
+++ b/code/AssetLib/Irr/IRRMeshLoader.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -62,8 +62,11 @@ namespace Assimp {
*/
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
public:
- IRRMeshImporter();
- ~IRRMeshImporter() override;
+ /// @brief The class constructor.
+ IRRMeshImporter() = default;
+
+ /// @brief The class destructor.
+ ~IRRMeshImporter() override = default;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
@@ -93,7 +96,7 @@ private:
tangent = 2, // "tangents" - standard + tangents and bitangents
};
- void ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
+ void ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
std::vector &vertices, std::vector &normals,
std::vector &tangents, std::vector &bitangents,
std::vector &UVs, std::vector &UV2s,
diff --git a/code/AssetLib/Irr/IRRShared.cpp b/code/AssetLib/Irr/IRRShared.cpp
index a47aeccba..9ab8d0899 100644
--- a/code/AssetLib/Irr/IRRShared.cpp
+++ b/code/AssetLib/Irr/IRRShared.cpp
@@ -135,21 +135,23 @@ void IrrlichtBase::ReadVectorProperty(VectorProperty &out, pugi::xml_node& vecto
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// three floats, separated with commas
const char *ptr = attrib.value();
+ size_t len = std::strlen(ptr);
+ const char *end = ptr + len;
- SkipSpaces(&ptr);
+ SkipSpaces(&ptr, end);
ptr = fast_atoreal_move(ptr, (float &)out.value.x);
- SkipSpaces(&ptr);
+ SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
- SkipSpaces(ptr + 1, &ptr);
+ SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move(ptr, (float &)out.value.y);
- SkipSpaces(&ptr);
+ SkipSpaces(&ptr, end);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
- SkipSpaces(ptr + 1, &ptr);
+ SkipSpaces(ptr + 1, &ptr, end);
}
ptr = fast_atoreal_move(ptr, (float &)out.value.z);
}
diff --git a/code/AssetLib/LWO/LWOBLoader.cpp b/code/AssetLib/LWO/LWOBLoader.cpp
index 4a9792b79..fc9132d88 100644
--- a/code/AssetLib/LWO/LWOBLoader.cpp
+++ b/code/AssetLib/LWO/LWOBLoader.cpp
@@ -152,7 +152,7 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
}
// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
+void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator &it,
LE_NCONST uint16_t*& cursor,
const uint16_t* const end,
unsigned int max) {
diff --git a/code/AssetLib/LWS/LWSLoader.cpp b/code/AssetLib/LWS/LWSLoader.cpp
index dec834495..4c3a44785 100644
--- a/code/AssetLib/LWS/LWSLoader.cpp
+++ b/code/AssetLib/LWS/LWSLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -78,14 +78,14 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Recursive parsing of LWS files
-void LWS::Element::Parse(const char *&buffer) {
- for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
+void LWS::Element::Parse(const char *&buffer, const char *end) {
+ for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
// begin of a new element with children
bool sub = false;
if (*buffer == '{') {
++buffer;
- SkipSpaces(&buffer);
+ SkipSpaces(&buffer, end);
sub = true;
} else if (*buffer == '}')
return;
@@ -98,16 +98,15 @@ void LWS::Element::Parse(const char *&buffer) {
while (!IsSpaceOrNewLine(*buffer))
++buffer;
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
- SkipSpaces(&buffer);
+ SkipSpaces(&buffer, end);
if (children.back().tokens[0] == "Plugin") {
ASSIMP_LOG_VERBOSE_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't
// follow LWS syntax, so we skip over it
- for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
+ for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
if (!::strncmp(buffer, "EndPlugin", 9)) {
- //SkipLine(&buffer);
break;
}
}
@@ -122,7 +121,7 @@ void LWS::Element::Parse(const char *&buffer) {
// parse more elements recursively
if (sub) {
- children.back().Parse(buffer);
+ children.back().Parse(buffer, end);
}
}
}
@@ -155,6 +154,8 @@ const aiImporterDesc *LWSImporter::GetInfo() const {
return &desc;
}
+static constexpr int MagicHackNo = 150392;
+
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWSImporter::SetupProperties(const Importer *pImp) {
@@ -163,11 +164,11 @@ void LWSImporter::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_LWS_ANIM_START
first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
- 150392 /* magic hack */);
+ MagicHackNo /* magic hack */);
// AI_CONFIG_IMPORT_LWS_ANIM_END
last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
- 150392 /* magic hack */);
+ MagicHackNo /* magic hack */);
if (last < first) {
std::swap(last, first);
@@ -191,15 +192,16 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
for (++it; it != dad.children.end(); ++it) {
const char *c = (*it).tokens[1].c_str();
+ const char *end = c + (*it).tokens[1].size();
if ((*it).tokens[0] == "Key") {
fill.keys.emplace_back();
LWO::Key &key = fill.keys.back();
float f;
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, key.value);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, f);
key.time = f;
@@ -231,13 +233,13 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
ASSIMP_LOG_ERROR("LWS: Unknown span type");
}
for (unsigned int i = 0; i < num; ++i) {
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, key.params[i]);
}
} else if ((*it).tokens[0] == "Behaviors") {
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
fill.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
}
}
@@ -245,47 +247,45 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
// ------------------------------------------------------------------------------------------------
// Read animation channels in the old LightWave animation format
-void LWSImporter::ReadEnvelope_Old(
- std::list::const_iterator &it,
- const std::list::const_iterator &end,
- LWS::NodeDesc &nodes,
- unsigned int /*version*/) {
- unsigned int num, sub_num;
- if (++it == end) goto unexpected_end;
+void LWSImporter::ReadEnvelope_Old(std::list::const_iterator &it,const std::list::const_iterator &endIt,
+ LWS::NodeDesc &nodes, unsigned int) {
+ if (++it == endIt) {
+ ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
+ return;
+ }
- num = strtoul10((*it).tokens[0].c_str());
+ const unsigned int num = strtoul10((*it).tokens[0].c_str());
for (unsigned int i = 0; i < num; ++i) {
-
nodes.channels.emplace_back();
LWO::Envelope &envl = nodes.channels.back();
envl.index = i;
envl.type = (LWO::EnvelopeType)(i + 1);
- if (++it == end) {
- goto unexpected_end;
+ if (++it == endIt) {
+ ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
+ return;
}
- sub_num = strtoul10((*it).tokens[0].c_str());
-
+
+ const unsigned int sub_num = strtoul10((*it).tokens[0].c_str());
for (unsigned int n = 0; n < sub_num; ++n) {
-
- if (++it == end) goto unexpected_end;
+ if (++it == endIt) {
+ ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
+ return;
+ }
// parse value and time, skip the rest for the moment.
LWO::Key key;
const char *c = fast_atoreal_move((*it).tokens[0].c_str(), key.value);
- SkipSpaces(&c);
+ const char *end = c + (*it).tokens[0].size();
+ SkipSpaces(&c, end);
float f;
fast_atoreal_move((*it).tokens[0].c_str(), f);
key.time = f;
- envl.keys.push_back(key);
+ envl.keys.emplace_back(key);
}
}
- return;
-
-unexpected_end:
- ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
}
// ------------------------------------------------------------------------------------------------
@@ -296,7 +296,6 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
// the name depends on the type. We break LWS's strange naming convention
// and return human-readable, but still machine-parsable and unique, strings.
if (src.type == LWS::NodeDesc::OBJECT) {
-
if (src.path.length()) {
std::string::size_type s = src.path.find_last_of("\\/");
if (s == std::string::npos) {
@@ -501,7 +500,8 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Parse the file structure
LWS::Element root;
const char *dummy = &mBuffer[0];
- root.Parse(dummy);
+ const char *dummyEnd = dummy + mBuffer.size();
+ root.Parse(dummy, dummyEnd);
// Construct a Batch-importer to read more files recursively
BatchLoader batch(pIOHandler);
@@ -540,6 +540,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Now read all elements in a very straightforward manner
for (; it != root.children.end(); ++it) {
const char *c = (*it).tokens[1].c_str();
+ const char *end = c + (*it).tokens[1].size();
// 'FirstFrame': begin of animation slice
if ((*it).tokens[0] == "FirstFrame") {
@@ -567,14 +568,14 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
LWS::NodeDesc d;
d.type = LWS::NodeDesc::OBJECT;
if (version >= 4) { // handle LWSC 4 explicit ID
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
d.number = strtoul16(c, &c) & AI_LWS_MASK;
} else {
d.number = cur_object++;
}
// and add the file to the import list
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
std::string path = FindLWOFile(c);
d.path = path;
d.id = batch.AddLoadRequest(path, 0, &props);
@@ -588,7 +589,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
} else {
d.number = cur_object++;
}
@@ -604,7 +605,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
d.type = LWS::NodeDesc::OBJECT;
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
} else {
d.number = cur_object++;
}
@@ -668,26 +669,25 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// two ints per envelope
LWO::Envelope &env = *envelopeIt;
env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
}
}
}
// 'ParentItem': specifies the parent of the current element
else if ((*it).tokens[0] == "ParentItem") {
- if (nodes.empty())
+ if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
-
- else
+ } else {
nodes.back().parent = strtoul16(c, &c);
+ }
}
// 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") {
- if (nodes.empty())
+ if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
-
- else {
+ } else {
nodes.back().parent = strtoul10(c, &c) | (1u << 28u);
}
}
@@ -700,19 +700,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
- } else
+ } else {
d.number = cur_camera++;
+ }
nodes.push_back(d);
num_camera++;
}
// 'CameraName': set name of currently active camera
else if ((*it).tokens[0] == "CameraName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
-
- else
+ } else {
nodes.back().name = c;
+ }
}
// 'AddLight': add a light to the scenegraph
else if ((*it).tokens[0] == "AddLight") {
@@ -723,19 +724,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
- } else
+ } else {
d.number = cur_light++;
+ }
nodes.push_back(d);
num_light++;
}
// 'LightName': set name of currently active light
else if ((*it).tokens[0] == "LightName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
-
- else
+ } else {
nodes.back().name = c;
+ }
}
// 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
@@ -753,62 +755,58 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
// 'LightType': set type of currently active light
else if ((*it).tokens[0] == "LightType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
-
- else
+ } else {
nodes.back().lightType = strtoul10(c);
-
+ }
}
// 'LightFalloffType': set falloff type of currently active light
else if ((*it).tokens[0] == "LightFalloffType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
- else
+ } else {
nodes.back().lightFalloffType = strtoul10(c);
-
+ }
}
// 'LightConeAngle': set cone angle of currently active light
else if ((*it).tokens[0] == "LightConeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
-
- else
+ } else {
nodes.back().lightConeAngle = fast_atof(c);
-
+ }
}
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
else if ((*it).tokens[0] == "LightEdgeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
-
- else
+ } else {
nodes.back().lightEdgeAngle = fast_atof(c);
-
+ }
}
// 'LightColor': set color of currently active light
else if ((*it).tokens[0] == "LightColor") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
+ if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
-
- else {
+ } else {
c = fast_atoreal_move(c, (float &)nodes.back().lightColor.r);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, (float &)nodes.back().lightColor.g);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, (float &)nodes.back().lightColor.b);
}
}
// 'PivotPosition': position of local transformation origin
else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
- if (nodes.empty())
+ if (nodes.empty()) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
- else {
+ } else {
c = fast_atoreal_move(c, (float &)nodes.back().pivotPos.x);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, (float &)nodes.back().pivotPos.y);
- SkipSpaces(&c);
+ SkipSpaces(&c, end);
c = fast_atoreal_move(c, (float &)nodes.back().pivotPos.z);
// Mark pivotPos as set
nodes.back().isPivotSet = true;
@@ -818,7 +816,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// resolve parenting
for (std::list::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
-
// check whether there is another node which calls us a parent
for (std::list::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
if (dit != ndIt && *ndIt == (*dit).parent) {
@@ -854,7 +851,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
aiNode *nd = master->mRootNode = new aiNode();
// allocate storage for cameras&lights
- if (num_camera) {
+ if (num_camera > 0u) {
master->mCameras = new aiCamera *[master->mNumCameras = num_camera];
}
aiCamera **cams = master->mCameras;
diff --git a/code/AssetLib/LWS/LWSLoader.h b/code/AssetLib/LWS/LWSLoader.h
index 4e92ef0d5..5db6852c1 100644
--- a/code/AssetLib/LWS/LWSLoader.h
+++ b/code/AssetLib/LWS/LWSLoader.h
@@ -76,7 +76,7 @@ public:
std::list children;
//! Recursive parsing function
- void Parse(const char *&buffer);
+ void Parse(const char *&buffer, const char *end);
};
#define AI_LWS_MASK (0xffffffff >> 4u)
diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp
index e743889e3..e4179d05d 100644
--- a/code/AssetLib/MD3/MD3Loader.cpp
+++ b/code/AssetLib/MD3/MD3Loader.cpp
@@ -123,12 +123,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// remove comments from it (C++ style)
CommentRemover::RemoveLineComments("//", &_buff[0]);
const char *buff = &_buff[0];
-
+ const char *end = buff + _buff.size();
Q3Shader::ShaderDataBlock *curData = nullptr;
Q3Shader::ShaderMapBlock *curMap = nullptr;
// read line per line
- for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
+ for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
if (*buff == '{') {
++buff;
@@ -140,21 +140,21 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
}
// read this data section
- for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
+ for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
if (*buff == '{') {
++buff;
// add new map section
curData->maps.emplace_back();
curMap = &curData->maps.back();
- for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
+ for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
// 'map' - Specifies texture file name
if (TokenMatchI(buff, "map", 3) || TokenMatchI(buff, "clampmap", 8)) {
- curMap->name = GetNextToken(buff);
+ curMap->name = GetNextToken(buff, end);
}
// 'blendfunc' - Alpha blending mode
else if (TokenMatchI(buff, "blendfunc", 9)) {
- const std::string blend_src = GetNextToken(buff);
+ const std::string blend_src = GetNextToken(buff, end);
if (blend_src == "add") {
curMap->blend_src = Q3Shader::BLEND_GL_ONE;
curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
@@ -166,12 +166,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
} else {
curMap->blend_src = StringToBlendFunc(blend_src);
- curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
+ curMap->blend_dest = StringToBlendFunc(GetNextToken(buff, end));
}
}
// 'alphafunc' - Alpha testing mode
else if (TokenMatchI(buff, "alphafunc", 9)) {
- const std::string at = GetNextToken(buff);
+ const std::string at = GetNextToken(buff, end);
if (at == "GT0") {
curMap->alpha_test = Q3Shader::AT_GT0;
} else if (at == "LT128") {
@@ -186,7 +186,6 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
break;
}
}
-
} else if (*buff == '}') {
++buff;
curData = nullptr;
@@ -195,7 +194,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// 'cull' specifies culling behaviour for the model
else if (TokenMatchI(buff, "cull", 4)) {
- SkipSpaces(&buff);
+ SkipSpaces(&buff, end);
if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug)
curData->cull = Q3Shader::CULL_CCW;
} else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders
@@ -213,9 +212,10 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
curData = &fill.blocks.back();
// get the name of this section
- curData->name = GetNextToken(buff);
+ curData->name = GetNextToken(buff, end);
}
}
+
return true;
}
@@ -232,6 +232,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
const size_t s = file->FileSize();
std::vector _buff(s + 1);
const char *buff = &_buff[0];
+ const char *end = buff + _buff.size();
file->Read(&_buff[0], s, 1);
_buff[s] = 0;
@@ -240,10 +241,10 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
// read token by token and fill output table
for (; *buff;) {
- SkipSpacesAndLineEnd(&buff);
+ SkipSpacesAndLineEnd(&buff, end);
// get first identifier
- std::string ss = GetNextToken(buff);
+ std::string ss = GetNextToken(buff, end);
// ignore tokens starting with tag_
if (!::strncmp(&ss[0], "tag_", std::min((size_t)4, ss.length())))
@@ -253,8 +254,9 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
SkinData::TextureEntry &entry = fill.textures.back();
entry.first = ss;
- entry.second = GetNextToken(buff);
+ entry.second = GetNextToken(buff, end);
}
+
return true;
}
@@ -293,7 +295,7 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial *out, const ShaderDataBlock &s
// - in any case: set it as diffuse texture
//
// If the texture is using 'filter' blending
- // - take as lightmap
+ // - take as light-map
//
// Textures with alpha funcs
// - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
diff --git a/code/AssetLib/MD5/MD5Loader.cpp b/code/AssetLib/MD5/MD5Loader.cpp
index 697e758fb..d4cdc0c44 100644
--- a/code/AssetLib/MD5/MD5Loader.cpp
+++ b/code/AssetLib/MD5/MD5Loader.cpp
@@ -210,7 +210,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
const unsigned int guess = (unsigned int)(fWeightsPerVert * iNewNum);
meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
- for (FaceList::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
+ for (FaceArray::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
const aiFace &face = *iter;
for (unsigned int i = 0; i < 3; ++i) {
if (face.mIndices[0] >= meshSrc.mVertices.size()) {
@@ -231,7 +231,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH
-void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
+void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones) {
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
@@ -282,7 +282,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM
-void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
+void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneArray &bones, const aiNodeAnim **node_anims) {
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
@@ -402,7 +402,7 @@ void MD5Importer::LoadMD5MeshFile() {
// copy texture coordinates
aiVector3D *pv = mesh->mTextureCoords[0];
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
+ for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
pv->x = (*iter).mUV.x;
pv->y = 1.0f - (*iter).mUV.y; // D3D to OpenGL
pv->z = 0.0f;
@@ -412,7 +412,7 @@ void MD5Importer::LoadMD5MeshFile() {
unsigned int *piCount = new unsigned int[meshParser.mJoints.size()];
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
+ for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */
@@ -447,7 +447,7 @@ void MD5Importer::LoadMD5MeshFile() {
}
pv = mesh->mVertices;
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
+ for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
// compute the final vertex position from all single weights
*pv = aiVector3D();
@@ -585,14 +585,14 @@ void MD5Importer::LoadMD5AnimFile() {
// 1 tick == 1 frame
anim->mTicksPerSecond = animParser.fFrameRate;
- for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
+ for (FrameArray::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
double dTime = (double)(*iter).iIndex;
aiNodeAnim **pcAnimNode = anim->mChannels;
if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
{
// now process all values in there ... read all joints
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
- for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
+ for (AnimBoneArray::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
++pcAnimNode, ++pcBaseFrame) {
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
diff --git a/code/AssetLib/MD5/MD5Loader.h b/code/AssetLib/MD5/MD5Loader.h
index c213c04e6..d64d6f5b8 100644
--- a/code/AssetLib/MD5/MD5Loader.h
+++ b/code/AssetLib/MD5/MD5Loader.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -118,7 +118,7 @@ protected:
* @param node_anims Generated node animations
*/
void AttachChilds_Anim(int iParentID, aiNode *piParent,
- AnimBoneList &bones, const aiNodeAnim **node_anims);
+ AnimBoneArray &bones, const aiNodeAnim **node_anims);
// -------------------------------------------------------------------
/** Construct node hierarchy from a given MD5MESH
@@ -126,7 +126,7 @@ protected:
* @param piParent Parent node to attach to
* @param bones Input bones
*/
- void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones);
+ void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones);
// -------------------------------------------------------------------
/** Build unique vertex buffers from a given MD5ANIM
diff --git a/code/AssetLib/MD5/MD5Parser.cpp b/code/AssetLib/MD5/MD5Parser.cpp
index 8da30e28f..24882af7e 100644
--- a/code/AssetLib/MD5/MD5Parser.cpp
+++ b/code/AssetLib/MD5/MD5Parser.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2023, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -138,14 +138,16 @@ bool MD5Parser::ParseSection(Section &out) {
char *sz = buffer;
while (!IsSpaceOrNewLine(*buffer)) {
++buffer;
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
while (IsSpace(*buffer)) {
++buffer;
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
bool running = true;
@@ -153,14 +155,16 @@ bool MD5Parser::ParseSection(Section &out) {
if ('{' == *buffer) {
// it is a normal section so read all lines
++buffer;
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
bool run = true;
while (run) {
while (IsSpaceOrNewLine(*buffer)) {
++buffer;
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
if ('\0' == *buffer) {
return false; // seems this was the last section
@@ -175,18 +179,21 @@ bool MD5Parser::ParseSection(Section &out) {
elem.iLineNumber = lineNumber;
elem.szStart = buffer;
+ elem.end = bufferEnd;
// terminate the line with zero
while (!IsLineEnd(*buffer)) {
++buffer;
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
if (*buffer) {
++lineNumber;
*buffer++ = '\0';
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
}
break;
@@ -194,89 +201,107 @@ bool MD5Parser::ParseSection(Section &out) {
// it is an element at global scope. Parse its value and go on
sz = buffer;
while (!IsSpaceOrNewLine(*buffer++)) {
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
}
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
continue;
}
break;
}
- if (buffer == bufferEnd)
+ if (buffer == bufferEnd) {
return false;
+ }
while (IsSpaceOrNewLine(*buffer)) {
+ if (buffer == bufferEnd) {
+ break;
+ }
++buffer;
- if (buffer == bufferEnd)
- return false;
}
return '\0' != *buffer;
}
-// ------------------------------------------------------------------------------------------------
-// Some dirty macros just because they're so funny and easy to debug
-
// skip all spaces ... handle EOL correctly
-#define AI_MD5_SKIP_SPACES() \
- if (!SkipSpaces(&sz)) \
- MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
+inline void AI_MD5_SKIP_SPACES(const char **sz, const char *bufferEnd, int linenumber) {
+ if (!SkipSpaces(sz, bufferEnd)) {
+ MD5Parser::ReportWarning("Unexpected end of line", linenumber);
+ }
+}
// read a triple float in brackets: (1.0 1.0 1.0)
-#define AI_MD5_READ_TRIPLE(vec) \
- AI_MD5_SKIP_SPACES(); \
- if ('(' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move(sz, (float &)vec.x); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move(sz, (float &)vec.y); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move(sz, (float &)vec.z); \
- AI_MD5_SKIP_SPACES(); \
- if (')' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
+inline void AI_MD5_READ_TRIPLE(aiVector3D &vec, const char **sz, const char *bufferEnd, int linenumber) {
+ AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
+ if ('(' != **sz) {
+ MD5Parser::ReportWarning("Unexpected token: ( was expected", linenumber);
+ ++*sz;
+ }
+ ++*sz;
+ AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
+ *sz = fast_atoreal_move(*sz, (float &)vec.x);
+ AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
+ *sz = fast_atoreal_move(*sz, (float &)vec.y);
+ AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
+ *sz = fast_atoreal_move(*sz, (float &)vec.z);
+ AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
+ if (')' != **sz) {
+ MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
+ }
+ ++*sz;
+}
// parse a string, enclosed in quotation marks or not
-#define AI_MD5_PARSE_STRING(out) \
- bool bQuota = (*sz == '\"'); \
- const char *szStart = sz; \
- while (!IsSpaceOrNewLine(*sz)) \
- ++sz; \
- const char *szEnd = sz; \
- if (bQuota) { \
- szStart++; \
- if ('\"' != *(szEnd -= 1)) { \
- MD5Parser::ReportWarning("Expected closing quotation marks in string", \
- elem.iLineNumber); \
- continue; \
- } \
- } \
- out.length = (size_t)(szEnd - szStart); \
- ::memcpy(out.data, szStart, out.length); \
+inline bool AI_MD5_PARSE_STRING(const char **sz, const char *bufferEnd, aiString &out, int linenumber) {
+ bool bQuota = (**sz == '\"');
+ const char *szStart = *sz;
+ while (!IsSpaceOrNewLine(**sz)) {
+ ++*sz;
+ if (*sz == bufferEnd) break;
+ }
+ const char *szEnd = *sz;
+ if (bQuota) {
+ szStart++;
+ if ('\"' != *(szEnd -= 1)) {
+ MD5Parser::ReportWarning("Expected closing quotation marks in string", linenumber);
+ ++*sz;
+ }
+ }
+ out.length = (ai_uint32)(szEnd - szStart);
+ ::memcpy(out.data, szStart, out.length);
out.data[out.length] = '\0';
+ return true;
+}
+
// parse a string, enclosed in quotation marks
-#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
- out.length = 0; \
- while ('\"' != *sz && '\0' != *sz) \
- ++sz; \
- if ('\0' != *sz) { \
- const char *szStart = ++sz; \
- while ('\"' != *sz && '\0' != *sz) \
- ++sz; \
- if ('\0' != *sz) { \
- const char *szEnd = (sz++); \
- out.length = (ai_uint32)(szEnd - szStart); \
- ::memcpy(out.data, szStart, out.length); \
- } \
- } \
+inline void AI_MD5_PARSE_STRING_IN_QUOTATION(const char **sz, const char *bufferEnd, aiString &out) {
+ out.length = 0u;
+ while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
+ ++*sz;
+ }
+ if ('\0' != **sz) {
+ const char *szStart = ++(*sz);
+
+ while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
+ ++*sz;
+ }
+ if ('\0' != **sz) {
+ const char *szEnd = *sz;
+ ++*sz;
+ out.length = (ai_uint32)(szEnd - szStart);
+ ::memcpy(out.data, szStart, out.length);
+ }
+ }
out.data[out.length] = '\0';
+}
+
// ------------------------------------------------------------------------------------------------
// .MD5MESH parsing function
-MD5MeshParser::MD5MeshParser(SectionList &mSections) {
+MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5MeshParser begin");
// now parse all sections
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
+ for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numMeshes") {
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
} else if ((*iter).mName == "numJoints") {
@@ -288,14 +313,15 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
BoneDesc &desc = mJoints.back();
const char *sz = elem.szStart;
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
+
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
// negative values, at least -1, is allowed here
desc.mParentIndex = (int)strtol10(sz, &sz);
- AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
+ AI_MD5_READ_TRIPLE(desc.mPositionXYZ, &sz, elem.end, elem.iLineNumber);
+ AI_MD5_READ_TRIPLE(desc.mRotationQuat, &sz, elem.end, elem.iLineNumber); // normalized quaternion, so w is not there
}
} else if ((*iter).mName == "mesh") {
mMeshes.emplace_back();
@@ -306,52 +332,52 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
// shader attribute
if (TokenMatch(sz, "shader", 6)) {
- AI_MD5_SKIP_SPACES();
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
+ AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mShader);
}
// numverts attribute
else if (TokenMatch(sz, "numverts", 8)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mVertices.resize(strtoul10(sz));
}
// numtris attribute
else if (TokenMatch(sz, "numtris", 7)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mFaces.resize(strtoul10(sz));
}
// numweights attribute
else if (TokenMatch(sz, "numweights", 10)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
desc.mWeights.resize(strtoul10(sz));
}
// vert attribute
// "vert 0 ( 0.394531 0.513672 ) 0 1"
else if (TokenMatch(sz, "vert", 4)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = ::strtoul10(sz, &sz);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (idx >= desc.mVertices.size())
desc.mVertices.resize(idx + 1);
VertexDesc &vert = desc.mVertices[idx];
if ('(' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, (float &)vert.mUV.x);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, (float &)vert.mUV.y);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (')' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
vert.mFirstWeight = ::strtoul10(sz, &sz);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
vert.mNumWeights = ::strtoul10(sz, &sz);
}
// tri attribute
// "tri 0 15 13 12"
else if (TokenMatch(sz, "tri", 3)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = strtoul10(sz, &sz);
if (idx >= desc.mFaces.size())
desc.mFaces.resize(idx + 1);
@@ -359,24 +385,24 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
aiFace &face = desc.mFaces[idx];
face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int i = 0; i < 3; ++i) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
face.mIndices[i] = strtoul10(sz, &sz);
}
}
// weight attribute
// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
else if (TokenMatch(sz, "weight", 6)) {
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = strtoul10(sz, &sz);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (idx >= desc.mWeights.size())
desc.mWeights.resize(idx + 1);
WeightDesc &weight = desc.mWeights[idx];
weight.mBone = strtoul10(sz, &sz);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
sz = fast_atoreal_move(sz, weight.mWeight);
- AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
+ AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
}
}
}
@@ -386,12 +412,12 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
// ------------------------------------------------------------------------------------------------
// .MD5ANIM parsing function
-MD5AnimParser::MD5AnimParser(SectionList &mSections) {
+MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5AnimParser begin");
fFrameRate = 24.0f;
mNumAnimatedComponents = UINT_MAX;
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
+ for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "hierarchy") {
// "sheath" 0 63 6
for (const auto &elem : (*iter).mElements) {
@@ -399,18 +425,18 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
AnimBoneDesc &desc = mAnimatedBones.back();
const char *sz = elem.szStart;
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
// parent index - negative values are allowed (at least -1)
desc.mParentIndex = ::strtol10(sz, &sz);
// flags (highest is 2^6-1)
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
if (63 < (desc.iFlags = ::strtoul10(sz, &sz))) {
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section", elem.iLineNumber);
}
- AI_MD5_SKIP_SPACES();
+ AI_MD5_SKIP_SPACES(& sz, elem.end, elem.iLineNumber);
// index of the first animation keyframe component for this joint
desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
@@ -423,8 +449,8 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
mBaseFrames.emplace_back();
BaseFrameDesc &desc = mBaseFrames.back();
- AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.vRotationQuat);
+ AI_MD5_READ_TRIPLE(desc.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
+ AI_MD5_READ_TRIPLE(desc.vRotationQuat, &sz, elem.end, elem.iLineNumber);
}
} else if ((*iter).mName == "frame") {
if (!(*iter).mGlobalValue.length()) {
@@ -444,7 +470,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
// now read all elements (continuous list of floats)
for (const auto &elem : (*iter).mElements) {
const char *sz = elem.szStart;
- while (SkipSpacesAndLineEnd(&sz)) {
+ while (SkipSpacesAndLineEnd(&sz, elem.end)) {
float f;
sz = fast_atoreal_move(sz, f);
desc.mValues.push_back(f);
@@ -471,11 +497,11 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
// ------------------------------------------------------------------------------------------------
// .MD5CAMERA parsing function
-MD5CameraParser::MD5CameraParser(SectionList &mSections) {
+MD5CameraParser::MD5CameraParser(SectionArray &mSections) {
ASSIMP_LOG_DEBUG("MD5CameraParser begin");
fFrameRate = 24.0f;
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
+ for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numFrames") {
frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} else if ((*iter).mName == "frameRate") {
@@ -492,9 +518,9 @@ MD5CameraParser::MD5CameraParser(SectionList &mSections) {
frames.emplace_back();
CameraAnimFrameDesc &cur = frames.back();
- AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
- AI_MD5_READ_TRIPLE(cur.vRotationQuat);
- AI_MD5_SKIP_SPACES();
+ AI_MD5_READ_TRIPLE(cur.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
+ AI_MD5_READ_TRIPLE(cur.vRotationQuat, &sz, elem.end, elem.iLineNumber);
+ AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
cur.fFOV = fast_atof(sz);
}
}
diff --git a/code/AssetLib/MD5/MD5Parser.h b/code/AssetLib/MD5/MD5Parser.h
index 9b29fbe85..75e3c22f2 100644
--- a/code/AssetLib/MD5/MD5Parser.h
+++ b/code/AssetLib/MD5/MD5Parser.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2023, assimp team
+Copyright (c) 2006-2024, assimp team
All rights reserved.
@@ -68,12 +68,14 @@ struct Element {
//! Elements are terminated with \0
char* szStart;
+ const char *end;
+
//! Original line number (can be used in error messages
//! if a parsing error occurs)
unsigned int iLineNumber;
};
-using ElementList = std::vector;
+using ElementArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a section of a MD5 file (such as the mesh or the joints section)
@@ -86,7 +88,7 @@ struct Section {
unsigned int iLineNumber;
//! List of all elements which have been parsed in this section.
- ElementList mElements;
+ ElementArray mElements;
//! Name of the section
std::string mName;
@@ -96,7 +98,7 @@ struct Section {
std::string mGlobalValue;
};
-using SectionList = std::vector;
+using SectionArray = std::vector;
// ---------------------------------------------------------------------------
/** Basic information about a joint
@@ -132,7 +134,7 @@ struct BoneDesc : BaseJointDescription {
unsigned int mMap;
};
-using BoneList = std::vector;
+using BoneArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a bone (joint) descriptor in a MD5Anim file
@@ -145,7 +147,7 @@ struct AnimBoneDesc : BaseJointDescription {
unsigned int iFirstKeyIndex;
};
-using AnimBoneList = std::vector< AnimBoneDesc >;
+using AnimBoneArray = std::vector< AnimBoneDesc >;
// ---------------------------------------------------------------------------
/** Represents a base frame descriptor in a MD5Anim file
@@ -155,7 +157,7 @@ struct BaseFrameDesc {
aiVector3D vRotationQuat;
};
-using BaseFrameList = std::vector;
+using BaseFrameArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a camera animation frame in a MDCamera file
@@ -164,7 +166,7 @@ struct CameraAnimFrameDesc : BaseFrameDesc {
float fFOV;
};
-using CameraFrameList = std::vector;
+using CameraFrameArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a frame descriptor in a MD5Anim file
@@ -177,7 +179,7 @@ struct FrameDesc {
std::vector< float > mValues;
};
-using FrameList = std::vector;
+using FrameArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a vertex descriptor in a MD5 file
@@ -199,7 +201,7 @@ struct VertexDesc {
unsigned int mNumWeights;
};
-using VertexList = std::vector;
+using VertexArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a vertex weight descriptor in a MD5 file
@@ -216,27 +218,27 @@ struct WeightDesc {
aiVector3D vOffsetPosition;
};
-using WeightList = std::vector;
-using FaceList = std::vector;
+using WeightArray = std::vector;
+using FaceArray = std::vector;
// ---------------------------------------------------------------------------
/** Represents a mesh in a MD5 file
*/
struct MeshDesc {
//! Weights of the mesh
- WeightList mWeights;
+ WeightArray mWeights;
//! Vertices of the mesh
- VertexList mVertices;
+ VertexArray mVertices;
//! Faces of the mesh
- FaceList mFaces;
+ FaceArray mFaces;
//! Name of the shader (=texture) to be assigned to the mesh
aiString mShader;
};
-using MeshList = std::vector;
+using MeshArray = std::vector;
// ---------------------------------------------------------------------------
// Convert a quaternion to its usual representation
@@ -269,13 +271,13 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
- explicit MD5MeshParser(SectionList& mSections);
+ explicit MD5MeshParser(SectionArray& mSections);
//! List of all meshes
- MeshList mMeshes;
+ MeshArray mMeshes;
//! List of all joints
- BoneList mJoints;
+ BoneArray mJoints;
};
// remove this flag if you need to the bounding box data
@@ -292,20 +294,20 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
- explicit MD5AnimParser(SectionList& mSections);
+ explicit MD5AnimParser(SectionArray& mSections);
//! Output frame rate
float fFrameRate;
//! List of animation bones
- AnimBoneList mAnimatedBones;
+ AnimBoneArray mAnimatedBones;
//! List of base frames
- BaseFrameList mBaseFrames;
+ BaseFrameArray mBaseFrames;
//! List of animation frames
- FrameList mFrames;
+ FrameArray mFrames;
//! Number of animated components
unsigned int mNumAnimatedComponents;
@@ -322,7 +324,7 @@ public:
*
* @param mSections List of file sections (output of MD5Parser)
*/
- explicit MD5CameraParser(SectionList& mSections);
+ explicit MD5CameraParser(SectionArray& mSections);
//! Output frame rate
float fFrameRate;
@@ -331,7 +333,7 @@ public:
std::vector cuts;
//! Frames
- CameraFrameList frames;
+ CameraFrameArray frames;
};
// ---------------------------------------------------------------------------
@@ -375,7 +377,7 @@ public:
void ReportWarning (const char* warn);
//! List of all sections which have been read
- SectionList mSections;
+ SectionArray mSections;
private:
bool ParseSection(Section& out);
@@ -388,7 +390,7 @@ private:
private:
char* buffer;
- char* bufferEnd;
+ const char* bufferEnd;
unsigned int fileSize;
unsigned int lineNumber;
};
@@ -406,7 +408,7 @@ inline void MD5Parser::ReportError(const char* error) {
// -------------------------------------------------------------------
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
++lineNumber;
- return Assimp::SkipLine(in ,out);
+ return Assimp::SkipLine(in, out, bufferEnd);
}
// -------------------------------------------------------------------
@@ -450,7 +452,7 @@ inline bool MD5Parser::SkipSpacesAndLineEnd() {
// -------------------------------------------------------------------
inline bool MD5Parser::SkipSpaces() {
- return Assimp::SkipSpaces((const char**)&buffer);
+ return Assimp::SkipSpaces((const char**)&buffer, bufferEnd);
}
} // namespace Assimp
diff --git a/code/AssetLib/NFF/NFFLoader.cpp b/code/AssetLib/NFF/NFFLoader.cpp
index 78adc27bd..6191d6def 100644
--- a/code/AssetLib/NFF/NFFLoader.cpp
+++ b/code/AssetLib/NFF/NFFLoader.cpp
@@ -85,7 +85,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \
- SkipSpaces(&sz); \
+ SkipSpaces(&sz, lineEnd); \
if (!IsLineEnd(*sz)) sz = fast_atoreal_move(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------
@@ -111,7 +111,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
ASSIMP_LOG_WARN("NFF2: Unexpected EOF, can't read next token"); \
break; \
} \
- SkipSpaces(line, &sz); \
+ SkipSpaces(line, &sz, lineEnd); \
} while (IsLineEnd(*sz))
// ------------------------------------------------------------------------------------------------
@@ -148,9 +148,9 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output,
// No read the file line per line
char line[4096];
- const char *sz;
+ const char *sz, *lineEnd = &line[2095]+1;
while (GetNextLine(buffer, line)) {
- SkipSpaces(line, &sz);
+ SkipSpaces(line, &sz, lineEnd);
// 'version' defines the version of the file format
if (TokenMatch(sz, "version", 7)) {
@@ -198,18 +198,16 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output,
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
-void NFFImporter::InternReadFile(const std::string &pFile,
- aiScene *pScene, IOSystem *pIOHandler) {
- std::unique_ptr file(pIOHandler->Open(pFile, "rb"));
-
- // Check whether we can read from the file
- if (!file)
- throw DeadlyImportError("Failed to open NFF file ", pFile, ".");
+void NFFImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
+ std::unique_ptr stream(pIOHandler->Open(file, "rb"));
+ if (!stream) {
+ throw DeadlyImportError("Failed to open NFF file ", file, ".");
+ }
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector mBuffer2;
- TextFileToBuffer(file.get(), mBuffer2);
+ TextFileToBuffer(stream.get(), mBuffer2);
const char *buffer = &mBuffer2[0];
// mesh arrays - separate here to make the handling of the pointers below easier.
@@ -219,8 +217,10 @@ void NFFImporter::InternReadFile(const std::string &pFile,
std::vector meshesLocked;
char line[4096];
+ const char *lineEnd = &line[4096];
const char *sz;
+
// camera parameters
aiVector3D camPos, camUp(0.f, 1.f, 0.f), camLookAt(0.f, 0.f, 1.f);
ai_real angle = 45.f;
@@ -265,7 +265,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
CommentRemover::RemoveLineComments("//", &mBuffer2[0]);
while (GetNextLine(buffer, line)) {
- SkipSpaces(line, &sz);
+ SkipSpaces(line, &sz, lineEnd);
if (TokenMatch(sz, "version", 7)) {
ASSIMP_LOG_INFO("NFF (Sense8) file format: ", sz);
} else if (TokenMatch(sz, "viewpos", 7)) {
@@ -295,7 +295,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// material table - an external file
if (TokenMatch(sz, "mtable", 6)) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz3 = sz;
while (!IsSpaceOrNewLine(*sz))
++sz;
@@ -316,12 +316,12 @@ void NFFImporter::InternReadFile(const std::string &pFile,
std::string::size_type sepPos;
if ((std::string::npos == (sepPos = path.find_last_of('\\')) || !sepPos) &&
(std::string::npos == (sepPos = path.find_last_of('/')) || !sepPos)) {
- sepPos = pFile.find_last_of('\\');
+ sepPos = file.find_last_of('\\');
if (std::string::npos == sepPos) {
- sepPos = pFile.find_last_of('/');
+ sepPos = file.find_last_of('/');
}
if (std::string::npos != sepPos) {
- path = pFile.substr(0, sepPos + 1) + path;
+ path = file.substr(0, sepPos + 1) + path;
}
}
LoadNFF2MaterialTable(materialTable, path, pIOHandler);
@@ -351,7 +351,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// parse all other attributes in the line
while (true) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) break;
// color definition
@@ -403,23 +403,20 @@ void NFFImporter::InternReadFile(const std::string &pFile,
tempIdx.reserve(10);
for (unsigned int i = 0; i < num; ++i) {
AI_NFF2_GET_NEXT_TOKEN();
- SkipSpaces(line, &sz);
+ SkipSpaces(line, &sz, lineEnd);
unsigned int numIdx = strtoul10(sz, &sz);
// read all faces indices
if (numIdx) {
- // mesh.faces.push_back(numIdx);
- // tempIdx.erase(tempIdx.begin(),tempIdx.end());
tempIdx.resize(numIdx);
for (unsigned int a = 0; a < numIdx; ++a) {
- SkipSpaces(sz, &sz);
+ SkipSpaces(sz, &sz, lineEnd);
unsigned int m = strtoul10(sz, &sz);
if (m >= (unsigned int)tempPositions.size()) {
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
m = 0;
}
- // mesh.vertices.push_back (tempPositions[idx]);
tempIdx[a] = m;
}
}
@@ -432,7 +429,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
shader.color = aiColor3D(1.f, 1.f, 1.f);
aiColor4D c = aiColor4D(1.f, 1.f, 1.f, 1.f);
while (true) {
- SkipSpaces(sz, &sz);
+ SkipSpaces(sz, &sz, lineEnd);
if (IsLineEnd(*sz)) break;
// per-polygon colors
@@ -510,7 +507,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// Material ID?
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
matIdx = strtoul10(sz, &sz);
if (matIdx >= materialTable.size()) {
ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
@@ -527,7 +524,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
shader.specular = mat.specular;
shader.shininess = mat.shininess;
} else
- SkipToken(sz);
+ SkipToken(sz, lineEnd);
}
// search the list of all shaders we have for this object whether
@@ -649,7 +646,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
sz = &line[1];
out = currentMesh;
}
- SkipSpaces(sz, &sz);
+ SkipSpaces(sz, &sz, lineEnd);
unsigned int m = strtoul10(sz);
// ---- flip the face order
@@ -677,13 +674,13 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
if (out == currentMeshWithUVCoords) {
// FIX: in one test file this wraps over multiple lines
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) {
GetNextLine(buffer, line);
sz = line;
}
AI_NFF_PARSE_FLOAT(v.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
if (IsLineEnd(*sz)) {
GetNextLine(buffer, line);
sz = line;
@@ -717,7 +714,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// if the next one is NOT a number we assume it is a texture file name
// this feature is used by some NFF files on the internet and it has
// been implemented as it can be really useful
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
if (!IsNumeric(*sz)) {
// TODO: Support full file names with spaces and quotation marks ...
const char *p = sz;
@@ -731,10 +728,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
} else {
AI_NFF_PARSE_FLOAT(s.ambient); // optional
}
- }
- // 'shader' - other way to specify a texture
- else if (TokenMatch(sz, "shader", 6)) {
- SkipSpaces(&sz);
+ } else if (TokenMatch(sz, "shader", 6)) { // 'shader' - other way to specify a texture
+ SkipSpaces(&sz, lineEnd);
const char *old = sz;
while (!IsSpaceOrNewLine(*sz))
++sz;
@@ -889,7 +884,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'tess' - tessellation
else if (TokenMatch(sz, "tess", 4)) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
iTesselation = strtoul10(sz);
}
// 'from' - camera position
@@ -929,7 +924,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// '' - comment
else if ('#' == line[0]) {
const char *space;
- SkipSpaces(&line[1], &space);
+ SkipSpaces(&line[1], &space, lineEnd);
if (!IsLineEnd(*space)) {
ASSIMP_LOG_INFO(space);
}
diff --git a/code/AssetLib/OFF/OFFLoader.cpp b/code/AssetLib/OFF/OFFLoader.cpp
index ce8dfc2d4..37fc2d31a 100644
--- a/code/AssetLib/OFF/OFFLoader.cpp
+++ b/code/AssetLib/OFF/OFFLoader.cpp
@@ -84,10 +84,10 @@ const aiImporterDesc *OFFImporter::GetInfo() const {
// skip blank space, lines and comments
static void NextToken(const char **car, const char *end) {
- SkipSpacesAndLineEnd(car);
+ SkipSpacesAndLineEnd(car, end);
while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
- SkipLine(car);
- SkipSpacesAndLineEnd(car);
+ SkipLine(car, end);
+ SkipSpacesAndLineEnd(car, end);
}
}
@@ -195,6 +195,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
char line[4096];
buffer = car;
const char *sz = car;
+ const char *lineEnd = &line[4096];
// now read all vertex lines
for (unsigned int i = 0; i < numVertices; ++i) {
@@ -210,13 +211,13 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
for (unsigned int dim = 0; dim < dimensions; ++dim) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, *vec[dim]);
}
// if has homogeneous coordinate, divide others by this one
if (hasHomogenous) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
ai_real w = 1.;
sz = fast_atoreal_move(sz, w);
for (unsigned int dim = 0; dim < dimensions; ++dim) {
@@ -227,11 +228,11 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// read optional normals
if (hasNormals) {
aiVector3D &n = mesh->mNormals[i];
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)n.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)n.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
fast_atoreal_move(sz, (ai_real &)n.z);
}
@@ -241,22 +242,22 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// in theory should be testing type !
if (hasColors) {
aiColor4D &c = mesh->mColors[0][i];
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)c.r);
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)c.g);
} else {
c.g = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)c.b);
} else {
c.b = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)c.a);
} else {
c.a = 1.;
@@ -264,9 +265,9 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
if (hasTexCoord) {
aiVector3D &t = mesh->mTextureCoords[0][i];
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
sz = fast_atoreal_move(sz, (ai_real &)t.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
fast_atoreal_move(sz, (ai_real &)t.y);
}
}
@@ -280,7 +281,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
unsigned int idx;
sz = line;
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
idx = strtoul10(sz, &sz);
if (!idx || idx > 9) {
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
@@ -291,7 +292,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
faces->mNumIndices = idx;
faces->mIndices = new unsigned int[faces->mNumIndices];
for (unsigned int m = 0; m < faces->mNumIndices; ++m) {
- SkipSpaces(&sz);
+ SkipSpaces(&sz, lineEnd);
idx = strtoul10(sz, &sz);
if (idx >= numVertices) {
ASSIMP_LOG_ERROR("OFF: Vertex index is out of range");
diff --git a/code/AssetLib/Obj/ObjFileParser.cpp b/code/AssetLib/Obj/ObjFileParser.cpp
index acb3f074c..9f5522ed2 100644
--- a/code/AssetLib/Obj/ObjFileParser.cpp
+++ b/code/AssetLib/Obj/ObjFileParser.cpp
@@ -64,6 +64,7 @@ ObjFileParser::ObjFileParser() :
m_pModel(nullptr),
m_uiLine(0),
m_buffer(),
+ mEnd(&m_buffer[Buffersize]),
m_pIO(nullptr),
m_progress(nullptr),
m_originalObjFileName() {
@@ -97,8 +98,6 @@ ObjFileParser::ObjFileParser(IOStreamBuffer &streamBuffer, const std::stri
parseFile(streamBuffer);
}
-ObjFileParser::~ObjFileParser() = default;
-
void ObjFileParser::setBuffer(std::vector &buffer) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
@@ -121,6 +120,7 @@ void ObjFileParser::parseFile(IOStreamBuffer &streamBuffer) {
while (streamBuffer.getNextDataLine(buffer, '\\')) {
m_DataIt = buffer.begin();
m_DataItEnd = buffer.end();
+ mEnd = &buffer[buffer.size() - 1] + 1;
// Handle progress reporting
const size_t filePos(streamBuffer.getFilePos());
@@ -130,7 +130,7 @@ void ObjFileParser::parseFile(IOStreamBuffer &streamBuffer) {
m_progress->UpdateFileRead(processed, progressTotal);
}
- // handle cstype section end (http://paulbourke.net/dataformats/obj/)
+ // handle c-stype section end (http://paulbourke.net/dataformats/obj/)
if (insideCstype) {
switch (*m_DataIt) {
case 'e': {
@@ -301,18 +301,19 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() {
} else if (IsLineEnd(*tmp)) {
end_of_definition = true;
}
- if (!SkipSpaces(&tmp)) {
+ if (!SkipSpaces(&tmp, mEnd)) {
break;
}
const bool isNum(IsNumeric(*tmp) || isNanOrInf(tmp));
- SkipToken(tmp);
+ SkipToken(tmp, mEnd);
if (isNum) {
++numComponents;
}
- if (!SkipSpaces(&tmp)) {
+ if (!SkipSpaces(&tmp, mEnd)) {
break;
}
}
+
return numComponents;
}
@@ -487,8 +488,9 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
++iStep;
}
- if (iPos == 1 && !vt && vn)
+ if (iPos == 1 && !vt && vn) {
iPos = 2; // skip texture coords for normals if there are no tex coords
+ }
if (iVal > 0) {
// Store parsed index
@@ -577,8 +579,9 @@ void ObjFileParser::getMaterialDesc() {
// Get name
std::string strName(pStart, &(*m_DataIt));
strName = trim_whitespaces(strName);
- if (strName.empty())
+ if (strName.empty()) {
skip = true;
+ }
// If the current mesh has the same material, we simply ignore that 'usemtl' command
// There is no need to create another object or even mesh here
diff --git a/code/AssetLib/Obj/ObjFileParser.h b/code/AssetLib/Obj/ObjFileParser.h
index 0ed724461..f3e149838 100644
--- a/code/AssetLib/Obj/ObjFileParser.h
+++ b/code/AssetLib/Obj/ObjFileParser.h
@@ -41,6 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEPARSER_H_INC
#define OBJ_FILEPARSER_H_INC
+#include "ObjFileData.h"
+
#include
#include
#include
@@ -53,14 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
-namespace ObjFile {
-struct Model;
-struct Object;
-struct Material;
-struct Point3;
-struct Point2;
-} // namespace ObjFile
-
class ObjFileImporter;
class IOSystem;
class ProgressHandler;
@@ -79,7 +73,7 @@ public:
/// @brief Constructor with data array.
ObjFileParser(IOStreamBuffer &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
/// @brief Destructor
- ~ObjFileParser();
+ ~ObjFileParser() = default;
/// @brief If you want to load in-core data.
void setBuffer(std::vector &buffer);
/// @brief Model getter.
@@ -149,6 +143,7 @@ private:
unsigned int m_uiLine;
//! Helper buffer
char m_buffer[Buffersize];
+ const char *mEnd;
/// Pointer to IO system instance.
IOSystem *m_pIO;
//! Pointer to progress handler
diff --git a/code/AssetLib/Ply/PlyLoader.cpp b/code/AssetLib/Ply/PlyLoader.cpp
index a747ba5cd..f524e3a73 100644
--- a/code/AssetLib/Ply/PlyLoader.cpp
+++ b/code/AssetLib/Ply/PlyLoader.cpp
@@ -159,7 +159,8 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
mBuffer = (unsigned char *)&mBuffer2[0];
char *szMe = (char *)&this->mBuffer[0];
- SkipSpacesAndLineEnd(szMe, (const char **)&szMe);
+ const char *end = &mBuffer2[0] + mBuffer2.size();
+ SkipSpacesAndLineEnd(szMe, (const char **)&szMe, end);
// determine the format of the file data and construct the aiMesh
PLY::DOM sPlyDom;
@@ -167,7 +168,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (TokenMatch(szMe, "format", 6)) {
if (TokenMatch(szMe, "ascii", 5)) {
- SkipLine(szMe, (const char **)&szMe);
+ SkipLine(szMe, (const char **)&szMe, end);
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
if (mGeneratedMesh != nullptr) {
delete (mGeneratedMesh);
diff --git a/code/AssetLib/Ply/PlyParser.cpp b/code/AssetLib/Ply/PlyParser.cpp
index 662da805e..7dcc4d239 100644
--- a/code/AssetLib/Ply/PlyParser.cpp
+++ b/code/AssetLib/Ply/PlyParser.cpp
@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
-using namespace Assimp;
+namespace Assimp {
// ------------------------------------------------------------------------------------------------
PLY::EDataType PLY::Property::ParseDataType(std::vector &buffer) {
@@ -296,7 +296,7 @@ bool PLY::Element::ParseElement(IOStreamBuffer &streamBuffer, std::vector<
return true;
}
- //parse the number of occurrences of this element
+ // parse the number of occurrences of this element
const char *pCur = (char *)&buffer[0];
pOut->NumOccur = strtoul10(pCur, &pCur);
@@ -321,13 +321,13 @@ bool PLY::Element::ParseElement(IOStreamBuffer &streamBuffer, std::vector<
return true;
}
-// ------------------------------------------------------------------------------------------------
bool PLY::DOM::SkipSpaces(std::vector &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
+ const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
- ret = Assimp::SkipSpaces(pCur, &pCur);
+ ret = Assimp::SkipSpaces(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -339,10 +339,11 @@ bool PLY::DOM::SkipSpaces(std::vector &buffer) {
bool PLY::DOM::SkipLine(std::vector &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
+ const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
- ret = Assimp::SkipLine(pCur, &pCur);
+ ret = Assimp::SkipLine(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -369,10 +370,11 @@ bool PLY::DOM::TokenMatch(std::vector &buffer, const char *token, unsigned
bool PLY::DOM::SkipSpacesAndLineEnd(std::vector &buffer) {
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
+ const char *end = pCur + buffer.size();
bool ret = false;
if (pCur) {
const char *szCur = pCur;
- ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
+ ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur, end);
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
@@ -426,7 +428,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer &streamBuffer, std::vector
} else {
// ignore unknown header elements
if (!streamBuffer.getNextLine(buffer))
- return false;
+ return false;
}
}
@@ -446,7 +448,7 @@ bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer &streamBuffer, std
std::vector::iterator a = alElementData.begin();
// parse all element instances
- //construct vertices and faces
+ // construct vertices and faces
for (; i != alElements.end(); ++i, ++a) {
if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) {
PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), nullptr, loader);
@@ -528,7 +530,7 @@ bool PLY::DOM::ParseInstance(IOStreamBuffer &streamBuffer, DOM *p_pcOut, P
return false;
}
- //get next line after header
+ // get next line after header
streamBuffer.getNextLine(buffer);
if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader)) {
ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure");
@@ -558,23 +560,24 @@ bool PLY::ElementInstanceList::ParseInstanceList(
}
} else {
const char *pCur = (const char *)&buffer[0];
+ const char *end = pCur + buffer.size();
// be sure to have enough storage
for (unsigned int i = 0; i < pcElement->NumOccur; ++i) {
if (p_pcOut)
- PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]);
+ PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &p_pcOut->alInstances[i]);
else {
ElementInstance elt;
- PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt);
+ PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &elt);
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@@ -611,13 +614,13 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
// Create vertex or face
if (pcElement->eSemantic == EEST_Vertex) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadVertex(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_Face) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadFace(pcElement, &elt, i);
} else if (pcElement->eSemantic == EEST_TriStrip) {
- //call loader instance from here
+ // call loader instance from here
loader->LoadFace(pcElement, &elt, i);
}
}
@@ -626,7 +629,7 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
}
// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstance(const char *&pCur,
+bool PLY::ElementInstance::ParseInstance(const char *&pCur, const char *end,
const PLY::Element *pcElement,
PLY::ElementInstance *p_pcOut) {
ai_assert(nullptr != pcElement);
@@ -638,7 +641,7 @@ bool PLY::ElementInstance::ParseInstance(const char *&pCur,
std::vector::iterator i = p_pcOut->alProperties.begin();
std::vector::const_iterator a = pcElement->alProperties.begin();
for (; i != p_pcOut->alProperties.end(); ++i, ++a) {
- if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i)))) {
+ if (!(PLY::PropertyInstance::ParseInstance(pCur, end, &(*a), &(*i)))) {
ASSIMP_LOG_WARN("Unable to parse property instance. "
"Skipping this element instance");
@@ -678,13 +681,13 @@ bool PLY::ElementInstance::ParseInstanceBinary(
}
// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
- const PLY::Property *prop, PLY::PropertyInstance *p_pcOut) {
+bool PLY::PropertyInstance::ParseInstance(const char *&pCur, const char *end, const PLY::Property *prop,
+ PLY::PropertyInstance *p_pcOut) {
ai_assert(nullptr != prop);
ai_assert(nullptr != p_pcOut);
// skip spaces at the beginning
- if (!SkipSpaces(&pCur)) {
+ if (!SkipSpaces(&pCur, end)) {
return false;
}
@@ -699,7 +702,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
// parse all list elements
p_pcOut->avList.resize(iNum);
for (unsigned int i = 0; i < iNum; ++i) {
- if (!SkipSpaces(&pCur))
+ if (!SkipSpaces(&pCur, end))
return false;
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]);
@@ -711,7 +714,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v);
p_pcOut->avList.push_back(v);
}
- SkipSpacesAndLineEnd(&pCur);
+ SkipSpacesAndLineEnd(&pCur, end);
return true;
}
@@ -774,7 +777,7 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
ai_assert(nullptr != pCur);
ai_assert(nullptr != out);
- //calc element size
+ // calc element size
bool ret = true;
switch (eType) {
case EDT_UInt:
@@ -824,7 +827,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer &streamBuffer,
bool p_bBE) {
ai_assert(nullptr != out);
- //calc element size
+ // calc element size
unsigned int lsize = 0;
switch (eType) {
case EDT_Char:
@@ -852,11 +855,11 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer &streamBuffer,
break;
}
- //read the next file block if needed
+ // read the next file block if needed
if (bufferSize < lsize) {
std::vector nbuffer;
if (streamBuffer.getNextBlock(nbuffer)) {
- //concat buffer contents
+ // concat buffer contents
buffer = std::vector(buffer.end() - bufferSize, buffer.end());
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
nbuffer.clear();
@@ -958,4 +961,6 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer &streamBuffer,
return ret;
}
+} // namespace Assimp
+
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/code/AssetLib/Ply/PlyParser.h b/code/AssetLib/Ply/PlyParser.h
index 593791e92..0e362926e 100644
--- a/code/AssetLib/Ply/PlyParser.h
+++ b/code/AssetLib/Ply/PlyParser.h
@@ -324,7 +324,7 @@ public:
// -------------------------------------------------------------------
//! Parse a property instance
- static bool ParseInstance(const char* &pCur,
+ static bool ParseInstance(const char* &pCur, const char *end,
const Property* prop, PropertyInstance* p_pcOut);
// -------------------------------------------------------------------
@@ -364,7 +364,7 @@ public:
// -------------------------------------------------------------------
//! Parse an element instance
- static bool ParseInstance(const char* &pCur,
+ static bool ParseInstance(const char *&pCur, const char *end,
const Element* pcElement, ElementInstance* p_pcOut);
// -------------------------------------------------------------------
diff --git a/code/AssetLib/Raw/RawLoader.cpp b/code/AssetLib/Raw/RawLoader.cpp
index 4c5f852b0..338ca9efa 100644
--- a/code/AssetLib/Raw/RawLoader.cpp
+++ b/code/AssetLib/Raw/RawLoader.cpp
@@ -104,11 +104,12 @@ void RAWImporter::InternReadFile(const std::string &pFile,
// now read all lines
char line[4096];
+ const char *end = &line[4096];
while (GetNextLine(buffer, line)) {
// if the line starts with a non-numeric identifier, it marks
// the beginning of a new group
const char *sz = line;
- SkipSpaces(&sz);
+ SkipSpaces(&sz, end);
if (IsLineEnd(*sz)) continue;
if (!IsNumeric(*sz)) {
const char *sz2 = sz;
@@ -117,8 +118,8 @@ void RAWImporter::InternReadFile(const std::string &pFile,
const unsigned int length = (unsigned int)(sz2 - sz);
// find an existing group with this name
- for (std::vector::iterator it = outGroups.begin(), end = outGroups.end();
- it != end; ++it) {
+ for (std::vector::iterator it = outGroups.begin(), endIt = outGroups.end();
+ it != endIt; ++it) {
if (length == (*it).name.length() && !::strcmp(sz, (*it).name.c_str())) {
curGroup = it;
sz2 = nullptr;
@@ -134,7 +135,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
float data[12];
unsigned int num;
for (num = 0; num < 12; ++num) {
- if (!SkipSpaces(&sz) || !IsNumeric(*sz)) break;
+ if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
sz = fast_atoreal_move(sz, data[num]);
}
if (num != 12 && num != 9) {
diff --git a/code/AssetLib/SMD/SMDLoader.cpp b/code/AssetLib/SMD/SMDLoader.cpp
index 4b63dd9d0..1d02847c8 100644
--- a/code/AssetLib/SMD/SMDLoader.cpp
+++ b/code/AssetLib/SMD/SMDLoader.cpp
@@ -82,8 +82,10 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SMDImporter::SMDImporter() :
- configFrameID(),
- pScene( nullptr ),
+ configFrameID(),
+ mBuffer(),
+ mEnd(nullptr),
+ pScene(nullptr),
iFileSize( 0 ),
iSmallestFrame( INT_MAX ),
dLengthOfAnim( 0.0 ),
@@ -92,9 +94,6 @@ SMDImporter::SMDImporter() :
// empty
}
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SMDImporter::~SMDImporter() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@@ -632,13 +631,13 @@ void SMDImporter::ParseFile() {
// read line per line ...
for ( ;; ) {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
+ if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, mEnd)) {
break;
}
// "version \n", should be 1 for hl and hl2 SMD files
if (TokenMatch(szCurrent,"version",7)) {
- if(!SkipSpaces(szCurrent,&szCurrent)) break;
+ if(!SkipSpaces(szCurrent,&szCurrent, mEnd)) break;
if (1 != strtoul10(szCurrent,&szCurrent)) {
ASSIMP_LOG_WARN("SMD.version is not 1. This "
"file format is not known. Continuing happily ...");
@@ -647,26 +646,26 @@ void SMDImporter::ParseFile() {
}
// "nodes\n" - Starts the node section
if (TokenMatch(szCurrent,"nodes",5)) {
- ParseNodesSection(szCurrent,&szCurrent);
+ ParseNodesSection(szCurrent, &szCurrent, mEnd);
continue;
}
// "triangles\n" - Starts the triangle section
if (TokenMatch(szCurrent,"triangles",9)) {
- ParseTrianglesSection(szCurrent,&szCurrent);
+ ParseTrianglesSection(szCurrent, &szCurrent, mEnd);
continue;
}
// "vertexanimation\n" - Starts the vertex animation section
if (TokenMatch(szCurrent,"vertexanimation",15)) {
bHasUVs = false;
- ParseVASection(szCurrent,&szCurrent);
+ ParseVASection(szCurrent, &szCurrent, mEnd);
continue;
}
// "skeleton\n" - Starts the skeleton section
if (TokenMatch(szCurrent,"skeleton",8)) {
- ParseSkeletonSection(szCurrent,&szCurrent);
+ ParseSkeletonSection(szCurrent, &szCurrent, mEnd);
continue;
}
- SkipLine(szCurrent,&szCurrent);
+ SkipLine(szCurrent, &szCurrent, mEnd);
}
}
@@ -683,6 +682,7 @@ void SMDImporter::ReadSmd(const std::string &pFile, IOSystem* pIOHandler) {
// Allocate storage and copy the contents of the file to a memory buffer
mBuffer.resize(iFileSize + 1);
TextFileToBuffer(file.get(), mBuffer);
+ mEnd = &mBuffer[mBuffer.size() - 1] + 1;
iSmallestFrame = INT_MAX;
bHasUVs = true;
@@ -723,26 +723,26 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename) {
// ------------------------------------------------------------------------------------------------
// Parse the nodes section of the file
-void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut, const char *end) {
for ( ;; ) {
// "end\n" - Ends the nodes section
- if (0 == ASSIMP_strincmp(szCurrent,"end",3) && IsSpaceOrNewLine(*(szCurrent+3))) {
+ if (0 == ASSIMP_strincmp(szCurrent, "end", 3) && IsSpaceOrNewLine(*(szCurrent+3))) {
szCurrent += 4;
break;
}
- ParseNodeInfo(szCurrent,&szCurrent);
+ ParseNodeInfo(szCurrent,&szCurrent, end);
}
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
+ SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the triangles section of the file
-void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseTrianglesSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
// Parse a triangle, parse another triangle, parse the next triangle ...
// and so on until we reach a token that looks quite similar to "end"
for ( ;; ) {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
+ if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@@ -750,17 +750,17 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCu
if (TokenMatch(szCurrent,"end",3)) {
break;
}
- ParseTriangle(szCurrent,&szCurrent);
+ ParseTriangle(szCurrent,&szCurrent, end);
}
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
+ SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the vertex animation section of the file
-void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseVASection(const char *szCurrent, const char **szCurrentOut, const char *end) {
unsigned int iCurIndex = 0;
for ( ;; ) {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
+ if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@@ -774,10 +774,10 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
// NOTE: The doc says that time values COULD be negative ...
// NOTE2: this is the shape key -> valve docs
int iTime = 0;
- if(!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime) {
+ if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime) || configFrameID != (unsigned int)iTime) {
break;
}
- SkipLine(szCurrent,&szCurrent);
+ SkipLine(szCurrent,&szCurrent, end);
} else {
if(0 == iCurIndex) {
asTriangles.emplace_back();
@@ -785,7 +785,7 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
if (++iCurIndex == 3) {
iCurIndex = 0;
}
- ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
+ ParseVertex(szCurrent,&szCurrent, end, asTriangles.back().avVertices[iCurIndex],true);
}
}
@@ -794,16 +794,16 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
asTriangles.pop_back();
}
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
+ SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse the skeleton section of the file
-void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseSkeletonSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
int iTime = 0;
for ( ;; ) {
- if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
+ if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
break;
}
@@ -811,15 +811,15 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
if (TokenMatch(szCurrent,"end",3)) {
break;
} else if (TokenMatch(szCurrent,"time",4)) {
- // "time \n" - Specifies the current animation frame
- if(!ParseSignedInt(szCurrent,&szCurrent,iTime)) {
+ // "time \n" - Specifies the current animation frame
+ if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime)) {
break;
}
iSmallestFrame = std::min(iSmallestFrame,iTime);
- SkipLine(szCurrent,&szCurrent);
+ SkipLine(szCurrent, &szCurrent, end);
} else {
- ParseSkeletonElement(szCurrent,&szCurrent,iTime);
+ ParseSkeletonElement(szCurrent, &szCurrent, end, iTime);
}
}
*szCurrentOut = szCurrent;
@@ -827,16 +827,16 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
// ------------------------------------------------------------------------------------------------
#define SMDI_PARSE_RETURN { \
- SkipLine(szCurrent,&szCurrent); \
+ SkipLine(szCurrent,&szCurrent, end); \
*szCurrentOut = szCurrent; \
return; \
}
// ------------------------------------------------------------------------------------------------
// Parse a node line
-void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseNodeInfo(const char *szCurrent, const char **szCurrentOut, const char *end) {
unsigned int iBone = 0;
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- if ( !ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent)) {
+ SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
+ if ( !ParseUnsignedInt(szCurrent, &szCurrent, end, iBone) || !SkipSpaces(szCurrent,&szCurrent, end)) {
throw DeadlyImportError("Unexpected EOF/EOL while parsing bone index");
}
if (iBone == UINT_MAX) {
@@ -877,7 +877,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
szCurrent = szEnd;
// the only negative bone parent index that could occur is -1 AFAIK
- if(!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent)) {
+ if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)bone.iParent)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
SMDI_PARSE_RETURN;
}
@@ -888,12 +888,12 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
// ------------------------------------------------------------------------------------------------
// Parse a skeleton element
-void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCurrentOut,int iTime) {
+void SMDImporter::ParseSkeletonElement(const char *szCurrent, const char **szCurrentOut, const char *end, int iTime) {
aiVector3D vPos;
aiVector3D vRot;
unsigned int iBone = 0;
- if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone)) {
+ if (!ParseUnsignedInt(szCurrent, &szCurrent, end, iBone)) {
ASSIMP_LOG_ERROR("Unexpected EOF/EOL while parsing bone index");
SMDI_PARSE_RETURN;
}
@@ -907,27 +907,27 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
key.dTime = (double)iTime;
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
SMDI_PARSE_RETURN;
}
@@ -947,11 +947,11 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
// ------------------------------------------------------------------------------------------------
// Parse a triangle
-void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut) {
+void SMDImporter::ParseTriangle(const char *szCurrent, const char **szCurrentOut, const char *end) {
asTriangles.emplace_back();
SMD::Face& face = asTriangles.back();
- if(!SkipSpaces(szCurrent,&szCurrent)) {
+ if(!SkipSpaces(szCurrent, &szCurrent, end)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
return;
}
@@ -963,19 +963,19 @@ void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut
// ... and get the index that belongs to this file name
face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
+ SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
// load three vertices
for (auto &avVertex : face.avVertices) {
- ParseVertex(szCurrent,&szCurrent, avVertex);
+ ParseVertex(szCurrent, &szCurrent, end, avVertex);
}
*szCurrentOut = szCurrent;
}
// ------------------------------------------------------------------------------------------------
// Parse a float
-bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, float& out) {
- if(!SkipSpaces(&szCurrent)) {
+bool SMDImporter::ParseFloat(const char *szCurrent, const char **szCurrentOut, const char *end, float &out) {
+ if (!SkipSpaces(&szCurrent, end)) {
return false;
}
@@ -985,8 +985,8 @@ bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, f
// ------------------------------------------------------------------------------------------------
// Parse an unsigned int
-bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrentOut, unsigned int& out) {
- if(!SkipSpaces(&szCurrent)) {
+bool SMDImporter::ParseUnsignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, unsigned int &out) {
+ if(!SkipSpaces(&szCurrent, end)) {
return false;
}
@@ -996,8 +996,8 @@ bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrent
// ------------------------------------------------------------------------------------------------
// Parse a signed int
-bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOut, int& out) {
- if(!SkipSpaces(&szCurrent)) {
+bool SMDImporter::ParseSignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, int &out) {
+ if(!SkipSpaces(&szCurrent, end)) {
return false;
}
@@ -1008,37 +1008,37 @@ bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOu
// ------------------------------------------------------------------------------------------------
// Parse a vertex
void SMDImporter::ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
+ const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
bool bVASection /*= false*/) {
- if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent)) {
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
+ if (SkipSpaces(&szCurrent, end) && IsLineEnd(*szCurrent)) {
+ SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
+ return ParseVertex(szCurrent, szCurrentOut, end, vertex, bVASection);
}
- if(!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode)) {
+ if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)vertex.iParentNode)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x)) {
+ if(!ParseFloat(szCurrent,&szCurrent,end, (float&)vertex.nor.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y)) {
+ if(!ParseFloat(szCurrent,&szCurrent, end, (float&)vertex.nor.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.nor.z)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
SMDI_PARSE_RETURN;
}
@@ -1047,11 +1047,11 @@ void SMDImporter::ParseVertex(const char* szCurrent,
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.x)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.y)) {
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
SMDI_PARSE_RETURN;
}
@@ -1059,16 +1059,16 @@ void SMDImporter::ParseVertex(const char* szCurrent,
// now read the number of bones affecting this vertex
// all elements from now are fully optional, we don't need them
unsigned int iSize = 0;
- if(!ParseUnsignedInt(szCurrent,&szCurrent,iSize)) {
+ if(!ParseUnsignedInt(szCurrent, &szCurrent, end, iSize)) {
SMDI_PARSE_RETURN;
}
vertex.aiBoneLinks.resize(iSize,std::pair(0,0.0f));
for (auto &aiBoneLink : vertex.aiBoneLinks) {
- if(!ParseUnsignedInt(szCurrent,&szCurrent,aiBoneLink.first)) {
+ if(!ParseUnsignedInt(szCurrent, &szCurrent, end, aiBoneLink.first)) {
SMDI_PARSE_RETURN;
}
- if(!ParseFloat(szCurrent,&szCurrent,aiBoneLink.second)) {
+ if(!ParseFloat(szCurrent, &szCurrent, end, aiBoneLink.second)) {
SMDI_PARSE_RETURN;
}
}
@@ -1077,6 +1077,6 @@ void SMDImporter::ParseVertex(const char* szCurrent,
SMDI_PARSE_RETURN;
}
-}
+} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER
diff --git a/code/AssetLib/SMD/SMDLoader.h b/code/AssetLib/SMD/SMDLoader.h
index adf80ba14..8286aa5eb 100644
--- a/code/AssetLib/SMD/SMDLoader.h
+++ b/code/AssetLib/SMD/SMDLoader.h
@@ -162,7 +162,7 @@ struct Bone {
class ASSIMP_API SMDImporter : public BaseImporter {
public:
SMDImporter();
- ~SMDImporter() override;
+ ~SMDImporter() override = default;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
@@ -206,7 +206,7 @@ protected:
* the next section (or to EOF)
*/
void ParseTrianglesSection(const char* szCurrent,
- const char** szCurrentOut);
+ const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse the vertex animation section in VTA files
@@ -216,7 +216,7 @@ protected:
* the next section (or to EOF)
*/
void ParseVASection(const char* szCurrent,
- const char** szCurrentOut);
+ const char **szCurrentOu, const char *end);
// -------------------------------------------------------------------
/** Parse the nodes section of the SMD file
@@ -226,7 +226,7 @@ protected:
* the next section (or to EOF)
*/
void ParseNodesSection(const char* szCurrent,
- const char** szCurrentOut);
+ const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse the skeleton section of the SMD file
@@ -236,7 +236,7 @@ protected:
* the next section (or to EOF)
*/
void ParseSkeletonSection(const char* szCurrent,
- const char** szCurrentOut);
+ const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a single triangle in the SMD file
@@ -245,8 +245,7 @@ protected:
* \param szCurrentOut Receives the output cursor position
*/
void ParseTriangle(const char* szCurrent,
- const char** szCurrentOut);
-
+ const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a single vertex in the SMD file
@@ -256,7 +255,7 @@ protected:
* \param vertex Vertex to be filled
*/
void ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
+ const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
bool bVASection = false);
// -------------------------------------------------------------------
@@ -271,32 +270,31 @@ protected:
/** Parse a line in the skeleton section
*/
void ParseSkeletonElement(const char* szCurrent,
- const char** szCurrentOut,int iTime);
+ const char **szCurrentOut, const char *end, int iTime);
// -------------------------------------------------------------------
/** Parse a line in the nodes section
*/
void ParseNodeInfo(const char* szCurrent,
- const char** szCurrentOut);
-
+ const char **szCurrentOut, const char *end);
// -------------------------------------------------------------------
/** Parse a floating-point value
*/
bool ParseFloat(const char* szCurrent,
- const char** szCurrentOut, float& out);
+ const char **szCurrentOut, const char *end, float &out);
// -------------------------------------------------------------------
/** Parse an unsigned integer. There may be no sign!
*/
bool ParseUnsignedInt(const char* szCurrent,
- const char** szCurrentOut, unsigned int& out);
+ const char **szCurrentOut, const char *end, unsigned int &out);
// -------------------------------------------------------------------
/** Parse a signed integer. Signs (+,-) are handled.
*/
bool ParseSignedInt(const char* szCurrent,
- const char** szCurrentOut, int& out);
+ const char **szCurrentOut, const char *end, int &out);
// -------------------------------------------------------------------
/** Fix invalid time values in the file
@@ -304,7 +302,7 @@ protected:
void FixTimeValues();
// -------------------------------------------------------------------
- /** Add all children of a bone as subnodes to a node
+ /** Add all children of a bone as sub-nodes to a node
* \param pcNode Parent node
* \param iParent Parent bone index
*/
@@ -329,17 +327,15 @@ protected:
// -------------------------------------------------------------------
- inline bool SkipLine( const char* in, const char** out)
- {
- Assimp::SkipLine(in,out);
+ inline bool SkipLine( const char* in, const char** out, const char *end) {
+ Assimp::SkipLine(in, out, end);
++iLineNumber;
return true;
}
// -------------------------------------------------------------------
- inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
- {
+ inline bool SkipSpacesAndLineEnd(const char *in, const char **out, const char *end) {
++iLineNumber;
- return Assimp::SkipSpacesAndLineEnd(in,out);
+ return Assimp::SkipSpacesAndLineEnd(in, out, end);
}
private:
@@ -349,6 +345,7 @@ private:
/** Buffer to hold the loaded file */
std::vector mBuffer;
+ char *mEnd;
/** Output scene to be filled
*/
diff --git a/code/AssetLib/STEPParser/STEPFileReader.cpp b/code/AssetLib/STEPParser/STEPFileReader.cpp
index 2bcfa1755..58d9cacc4 100644
--- a/code/AssetLib/STEPParser/STEPFileReader.cpp
+++ b/code/AssetLib/STEPParser/STEPFileReader.cpp
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -40,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-/** @file STEPFileReader.cpp
+/**
+ * @file STEPFileReader.cpp
* @brief Implementation of the STEP file parser, which fills a
- * STEP::DB with data read from a file.
+ * STEP::DB with data read from a file.
*/
#include "STEPFileReader.h"
@@ -58,34 +58,28 @@ using namespace Assimp;
namespace EXPRESS = STEP::EXPRESS;
// ------------------------------------------------------------------------------------------------
-std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string())
-{
+std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast( (Formatter::format(),prefix,"(line ",line,") ",s) );
}
// ------------------------------------------------------------------------------------------------
-std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string())
-{
+std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast( (Formatter::format(),prefix,"(entity #",entity,") ",s));
}
// ------------------------------------------------------------------------------------------------
-STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line /* = LINE_NOT_SPECIFIED */)
-: DeadlyImportError(AddLineNumber(s,line))
-{
-
+STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line) : DeadlyImportError(AddLineNumber(s,line)) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
-STEP::TypeError::TypeError (const std::string& s,uint64_t entity /* = ENTITY_NOT_SPECIFIED */,uint64_t line /*= LINE_NOT_SPECIFIED*/)
-: DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line))
-{
-
+STEP::TypeError::TypeError (const std::string& s,uint64_t entity, uint64_t line) : DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line)) {
+ // empty
}
-static const char *ISO_Token = "ISO-10303-21;";
-static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
+static constexpr char ISO_Token[] = "ISO-10303-21;";
+static constexpr char FILE_SCHEMA_Token[] = "FILE_SCHEMA";
// ------------------------------------------------------------------------------------------------
STEP::DB* STEP::ReadFileHeader(std::shared_ptr stream) {
std::shared_ptr reader = std::shared_ptr(new StreamReaderLE(std::move(stream)));
@@ -110,8 +104,9 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr stream) {
if (s.substr(0,11) == FILE_SCHEMA_Token) {
const char* sz = s.c_str()+11;
- SkipSpaces(sz,&sz);
- std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz);
+ const char *end = s.c_str() + s.size();
+ SkipSpaces(sz,&sz, end);
+ std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz, end);
// the file schema should be a regular list entity, although it usually contains exactly one entry
// since the list itself is contained in a regular parameter list, we actually have
@@ -304,10 +299,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
}
// ------------------------------------------------------------------------------------------------
-std::shared_ptr EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
+std::shared_ptr EXPRESS::DataType::Parse(const char*& inout, const char *end, uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
{
const char* cur = inout;
- SkipSpaces(&cur);
+ SkipSpaces(&cur, end);
if (*cur == ',' || IsSpaceOrNewLine(*cur)) {
throw STEP::SyntaxError("unexpected token, expected parameter",line);
}
@@ -325,7 +320,7 @@ std::shared_ptr EXPRESS::DataType::Parse(const char*& i
std::transform(s.begin(),s.end(),s.begin(),&ai_tolower );
if (schema->IsKnownToken(s)) {
for(cur = t+1;*cur++ != '(';);
- std::shared_ptr dt = Parse(cur);
+ std::shared_ptr dt = Parse(cur, end);
inout = *cur ? cur+1 : cur;
return dt;
}
@@ -348,7 +343,7 @@ std::shared_ptr EXPRESS::DataType::Parse(const char*& i
else if (*cur == '(' ) {
// start of an aggregate, further parsing is done by the LIST factory constructor
inout = cur;
- return EXPRESS::LIST::Parse(inout,line,schema);
+ return EXPRESS::LIST::Parse(inout, end, line, schema);
}
else if (*cur == '.' ) {
// enum (includes boolean)
@@ -427,9 +422,10 @@ std::shared_ptr EXPRESS::DataType::Parse(const char*& i
}
// ------------------------------------------------------------------------------------------------
-std::shared_ptr EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/) {
+std::shared_ptr EXPRESS::LIST::Parse(const char*& inout, const char *end,
+ uint64_t line, const EXPRESS::ConversionSchema* schema) {
const std::shared_ptr list = std::make_shared();
- EXPRESS::LIST::MemberList& members = list->members;
+ EXPRESS::LIST::MemberList& cur_members = list->members;
const char* cur = inout;
if (*cur++ != '(') {
@@ -442,19 +438,19 @@ std::shared_ptr EXPRESS::LIST::Parse(const char*& inout,uin
count += (*c == ',' ? 1 : 0);
}
- members.reserve(count);
+ cur_members.reserve(count);
for(;;++cur) {
if (!*cur) {
throw STEP::SyntaxError("unexpected end of line while reading list");
}
- SkipSpaces(cur,&cur);
+ SkipSpaces(cur,&cur, end);
if (*cur == ')') {
break;
}
- members.push_back( EXPRESS::DataType::Parse(cur,line,schema));
- SkipSpaces(cur,&cur);
+ cur_members.push_back(EXPRESS::DataType::Parse(cur, end, line, schema));
+ SkipSpaces(cur, &cur, end);
if (*cur != ',') {
if (*cur == ')') {
@@ -464,7 +460,7 @@ std::shared_ptr EXPRESS::LIST::Parse(const char*& inout,uin
}
}
- inout = cur+1;
+ inout = cur + 1;
return list;
}
@@ -543,7 +539,8 @@ void STEP::LazyObject::LazyInit() const {
}
const char* acopy = args;
- std::shared_ptr conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
+ const char *end = acopy + std::strlen(args);
+ std::shared_ptr conv_args = EXPRESS::LIST::Parse(acopy, end, (uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args;
args = nullptr;
diff --git a/code/AssetLib/STEPParser/STEPFileReader.h b/code/AssetLib/STEPParser/STEPFileReader.h
index 8a57937c0..5a8eb7a6e 100644
--- a/code/AssetLib/STEPParser/STEPFileReader.h
+++ b/code/AssetLib/STEPParser/STEPFileReader.h
@@ -60,8 +60,7 @@ void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const*
/// @brief Helper to read a file.
template
-inline
-void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
+inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2);
}
diff --git a/code/AssetLib/STL/STLLoader.cpp b/code/AssetLib/STL/STLLoader.cpp
index 269ee1467..397aa59b1 100644
--- a/code/AssetLib/STL/STLLoader.cpp
+++ b/code/AssetLib/STL/STLLoader.cpp
@@ -98,7 +98,7 @@ static bool IsAsciiSTL(const char *buffer, size_t fileSize) {
const char *bufferEnd = buffer + fileSize;
- if (!SkipSpaces(&buffer)) {
+ if (!SkipSpaces(&buffer, bufferEnd)) {
return false;
}
@@ -244,11 +244,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
aiNode *node = new aiNode;
node->mParent = root;
nodes.push_back(node);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
ai_assert(!IsLineEnd(sz));
sz += 5; // skip the "solid"
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
const char *szMe = sz;
while (!IsSpaceOrNewLine(*sz)) {
sz++;
@@ -270,7 +270,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
unsigned int faceVertexCounter = 3;
for (;;) {
// go to the next token
- if (!SkipSpacesAndLineEnd(&sz)) {
+ if (!SkipSpacesAndLineEnd(&sz, bufferEnd)) {
// seems we're finished although there was no end marker
ASSIMP_LOG_WARN("STL: unexpected EOF. \'endsolid\' keyword was expected");
break;
@@ -284,7 +284,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
faceVertexCounter = 0;
sz += 6;
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
if (strncmp(sz, "normal", 6)) {
ASSIMP_LOG_WARN("STL: a facet normal vector was expected but not found");
} else {
@@ -293,11 +293,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
}
aiVector3D vn;
sz += 7;
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, (ai_real &)vn.x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, (ai_real &)vn.y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, (ai_real &)vn.z);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
@@ -312,13 +312,13 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
sz += 7;
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
positionBuffer.emplace_back();
aiVector3D *vn = &positionBuffer.back();
sz = fast_atoreal_move(sz, (ai_real &)vn->x);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, (ai_real &)vn->y);
- SkipSpaces(&sz);
+ SkipSpaces(&sz, bufferEnd);
sz = fast_atoreal_move(sz, (ai_real &)vn->z);
faceVertexCounter++;
}
@@ -326,7 +326,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
do {
++sz;
} while (!IsLineEnd(*sz));
- SkipSpacesAndLineEnd(&sz);
+ SkipSpacesAndLineEnd(&sz, bufferEnd);
// finished!
break;
} else { // else skip the whole identifier
diff --git a/code/AssetLib/Step/STEPFile.h b/code/AssetLib/Step/STEPFile.h
index 76a9370f5..e5da75b61 100644
--- a/code/AssetLib/Step/STEPFile.h
+++ b/code/AssetLib/Step/STEPFile.h
@@ -199,35 +199,27 @@ public:
}
public:
- /** parse a variable from a string and set 'inout' to the character
- * behind the last consumed character. An optional schema enables,
- * if specified, automatic conversion of custom data types.
- *
- * @throw SyntaxError
- */
- static std::shared_ptr Parse(const char *&inout,
- uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
- const EXPRESS::ConversionSchema *schema = nullptr);
+ /// @brief Parse a variable from a string and set 'inout' to the character behind the last consumed character.
+ ///
+ /// An optional schema enables, if specified, automatic conversion of custom data types.
+ ///
+ /// @throw SyntaxError
+ static std::shared_ptr Parse(const char *&inout, const char *end,
+ uint64_t line = SyntaxError::LINE_NOT_SPECIFIED, const EXPRESS::ConversionSchema *schema = nullptr);
};
typedef DataType SELECT;
typedef DataType LOGICAL;
// -------------------------------------------------------------------------------
-/** Sentinel class to represent explicitly unset (optional) fields ($) */
+/// Sentinel class to represent explicitly unset (optional) fields ($)
// -------------------------------------------------------------------------------
-class UNSET : public DataType {
-public:
-private:
-};
+class UNSET : public DataType {};
// -------------------------------------------------------------------------------
-/** Sentinel class to represent explicitly derived fields (*) */
+/// Sentinel class to represent explicitly derived fields (*)
// -------------------------------------------------------------------------------
-class ISDERIVED : public DataType {
-public:
-private:
-};
+class ISDERIVED : public DataType {};
// -------------------------------------------------------------------------------
/** Shared implementation for some of the primitive data type, i.e. int, float
@@ -304,7 +296,7 @@ public:
public:
/** @see DaraType::Parse
*/
- static std::shared_ptr Parse(const char *&inout,
+ static std::shared_ptr Parse(const char *&inout, const char *end,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
const EXPRESS::ConversionSchema *schema = nullptr);
diff --git a/code/AssetLib/Unreal/UnrealLoader.cpp b/code/AssetLib/Unreal/UnrealLoader.cpp
index 5f622da42..ab3f7c3be 100644
--- a/code/AssetLib/Unreal/UnrealLoader.cpp
+++ b/code/AssetLib/Unreal/UnrealLoader.cpp
@@ -320,17 +320,18 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
std::vector _data;
TextFileToBuffer(pb.get(), _data);
const char *data = &_data[0];
+ const char *end = &_data[_data.size() - 1] + 1;
std::vector> tempTextures;
// do a quick search in the UC file for some known, usually texture-related, tags
for (; *data; ++data) {
if (TokenMatchI(data, "#exec", 5)) {
- SkipSpacesAndLineEnd(&data);
+ SkipSpacesAndLineEnd(&data, end);
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
if (TokenMatchI(data, "TEXTURE", 7)) {
- SkipSpacesAndLineEnd(&data);
+ SkipSpacesAndLineEnd(&data, end);
if (TokenMatchI(data, "IMPORT", 6)) {
tempTextures.emplace_back();
@@ -348,14 +349,15 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
me.second = std::string(d, (size_t)(data - d));
}
}
- if (!me.first.length() || !me.second.length())
+ if (!me.first.length() || !me.second.length()) {
tempTextures.pop_back();
+ }
}
}
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
else if (TokenMatchI(data, "MESHMAP", 7)) {
- SkipSpacesAndLineEnd(&data);
+ SkipSpacesAndLineEnd(&data, end);
if (TokenMatchI(data, "SETTEXTURE", 10)) {
@@ -369,8 +371,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
} else if (!ASSIMP_strincmp(data, "TEXTURE=", 8)) {
data += 8;
const char *d = data;
- for (; !IsSpaceOrNewLine(*data); ++data)
- ;
+ for (; !IsSpaceOrNewLine(*data); ++data);
me.second = std::string(d, (size_t)(data - d));
// try to find matching path names, doesn't care if we don't find them
@@ -408,7 +409,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
// find out how many output meshes and materials we'll have and build material indices
for (Unreal::Triangle &tri : triangles) {
Unreal::TempMat mat(tri);
- std::vector::iterator nt = std::find(materials.begin(), materials.end(), mat);
+ auto nt = std::find(materials.begin(), materials.end(), mat);
if (nt == materials.end()) {
// add material
tri.matIndex = static_cast