Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release' into develop

  • Loading branch information...
commit ee5c049f076cdc2d85aa3021519fafa09b8876f1 2 parents 4737378 + dc51bc4
rt authored
View
5 buildbot/slave/validation/tests-cleanup.sh
@@ -6,11 +6,6 @@ set -e
TESTDIR=${TMP_BASE}/tests
-#FIXME/HACK reset directory permissions
-if [ -d ${TESTDIR}/usr/local/share/games/spring ]; then
- chmod 755 ${TESTDIR}/usr/local/share/games/spring
-fi
-
#cleanup
rm -rf ${TESTDIR}
View
5 buildbot/slave/validation/tests-prepare.sh
@@ -20,9 +20,6 @@ fi
cd ${BUILDDIR}
DESTDIR=${TESTDIR} ninja install-spring-headless install-pr-downloader demotool unitsyncTest lua2php
-# HACK/FIXME force spring to detect install dir as read-only
-chmod 555 ${TESTDIR}/usr/local/share/games/spring
-
cd ${SOURCEDIR}
function makescript {
@@ -66,7 +63,7 @@ cp -v ${SOURCEDIR}/test/validation/LuaUI/Config/ZK_data.lua ${CONTENT_DIR}/LuaUI
cp -v ${SOURCEDIR}/cont/springrc-template-headless.txt ${TESTDIR}/.springrc
#set data directory to test directory
-echo "SpringData = ${TESTDIR}/usr/local/share/games/spring" >> ${TESTDIR}/.springrc
+echo "SpringData = ${CONTENT_DIR}:${TESTDIR}/usr/local/share/games/spring" >> ${TESTDIR}/.springrc
makescript "$GAME1" "$MAP" AAI 0.9
makescript "$GAME1" "$MAP" E323AI 3.25.0
View
7 doc/changelog.txt
@@ -31,15 +31,18 @@ Bugfixes:
- fix #3545 (AddUnitImpulse() causes unit to move in random direction)
- fix #3544 (units briefly invisible when transferred to another team)
- fix #3490 (ships cannot be transported by aircraft)
+ - fix #3596 (in debug-mode the firing-cone visualisation of weapons points up)
- fix 'fix #3506 (wrong calculation of goffset for assimp model pieces)'
- fix pseudo-static units (nanotowers, etc) no longer being transportable
+ - fix #3569 (texturing for OBJ and ASS projectile models)
- fix OBJ models being parsed by assimp
- fix SEGV on exit
- - Fix flashing team colors
+ - fix flashing team colors
+ - fix some trees drawn after being destroyed
Lua:
- add Spring.UnitWeapon{Fire,HoldFire}(number unitID, number weaponID) --> nil
- - add callouts Spring.Weapon{TryTarget,TestTarget,TestRange,HaveFreeLineOfFire}(number attackerID, number attackeeID, number weaponID, number targetPosX, number targetPosY, number targetPosZ) --> boolean
+ - add callouts Spring.GetUnitWeapon{TryTarget,TestTarget,TestRange,HaveFreeLineOfFire}(number attackerID, number weaponID, number attackeeID | [number targetPosX, number targetPosY, number targetPosZ]) --> boolean
- add Spring.SetProjectileTarget(number projectileID, [number objectID, string objectType] | [number x, number y, number z]) --> boolean
- add Spring.GetProjectileTarget(number projectileID) --> number targetID, string targetType
- add Spring.SpawnProjectile(number weaponDefID, table projectileParams) --> number projectileID | nil
View
12 rts/Game/GameVersion.cpp
@@ -76,20 +76,20 @@ std::string GetAdditional()
#define GV_ADD_SPACE " "
#endif
-#if defined USE_GML
- GV_ADD_SPACE "GML"
+#if defined USE_GML_SIM
+ GV_ADD_SPACE "ASIM"
#undef GV_ADD_SPACE
#define GV_ADD_SPACE " "
#endif
-#if defined USE_GML_DEBUG
- GV_ADD_SPACE "GDB"
+#if defined USE_GML
+ GV_ADD_SPACE "GML"
#undef GV_ADD_SPACE
#define GV_ADD_SPACE " "
#endif
-#if defined USE_GML_SIM
- GV_ADD_SPACE "ASIM"
+#if defined USE_GML_DEBUG
+ GV_ADD_SPACE "GDB"
#undef GV_ADD_SPACE
#define GV_ADD_SPACE " "
#endif
View
173 rts/Lua/LuaSyncedRead.cpp
@@ -221,6 +221,9 @@ bool LuaSyncedRead::PushEntries(lua_State* L)
REGISTER_LUA_CFUNC(GetUnitWeaponState);
REGISTER_LUA_CFUNC(GetUnitWeaponVectors);
REGISTER_LUA_CFUNC(GetUnitWeaponTryTarget);
+ REGISTER_LUA_CFUNC(GetUnitWeaponTestTarget);
+ REGISTER_LUA_CFUNC(GetUnitWeaponTestRange);
+ REGISTER_LUA_CFUNC(GetUnitWeaponHaveFreeLineOfFire);
REGISTER_LUA_CFUNC(GetUnitTravel);
REGISTER_LUA_CFUNC(GetUnitFuel);
REGISTER_LUA_CFUNC(GetUnitEstimatedPath);
@@ -303,11 +306,6 @@ bool LuaSyncedRead::PushEntries(lua_State* L)
REGISTER_LUA_CFUNC(GetUnitScriptPiece);
REGISTER_LUA_CFUNC(GetUnitScriptNames);
- REGISTER_LUA_CFUNC(WeaponTryTarget);
- REGISTER_LUA_CFUNC(WeaponTestTarget);
- REGISTER_LUA_CFUNC(WeaponTestRange);
- REGISTER_LUA_CFUNC(WeaponHaveFreeLineOfFire);
-
REGISTER_LUA_CFUNC(GetCOBUnitVar);
REGISTER_LUA_CFUNC(GetCOBTeamVar);
REGISTER_LUA_CFUNC(GetCOBAllyTeamVar);
@@ -3257,7 +3255,7 @@ int LuaSyncedRead::GetUnitWeaponTryTarget(lua_State* L)
return 0;
}
- const CWeapon* weapon = unit->weapons[weaponNum];
+ const CWeapon* weapon = unit->weapons[weaponNum];
const CUnit* enemy = NULL;
float3 pos;
@@ -3275,6 +3273,94 @@ int LuaSyncedRead::GetUnitWeaponTryTarget(lua_State* L)
}
+int LuaSyncedRead::GetUnitWeaponTestTarget(lua_State* L)
+{
+ CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
+ if (unit == NULL) {
+ return 0;
+ }
+ const int weaponNum = luaL_checkint(L, 2);
+ if ((weaponNum < 0) || ((size_t)weaponNum >= unit->weapons.size())) {
+ return 0;
+ }
+
+ const CWeapon* weapon = unit->weapons[weaponNum];
+ const CUnit* enemy = NULL;
+
+ float3 pos;
+
+ if (lua_gettop(L) >= 5) {
+ pos.x = luaL_optnumber(L, 3, 0.0f);
+ pos.y = luaL_optnumber(L, 4, 0.0f);
+ pos.z = luaL_optnumber(L, 5, 0.0f);
+ } else {
+ enemy = ParseUnit(L, __FUNCTION__, 3);
+ }
+
+ lua_pushboolean(L, weapon->TestTarget(pos, true, enemy));
+ return 1;
+}
+
+
+int LuaSyncedRead::GetUnitWeaponTestRange(lua_State* L)
+{
+ CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
+ if (unit == NULL) {
+ return 0;
+ }
+ const int weaponNum = luaL_checkint(L, 2);
+ if ((weaponNum < 0) || ((size_t)weaponNum >= unit->weapons.size())) {
+ return 0;
+ }
+
+ const CWeapon* weapon = unit->weapons[weaponNum];
+ const CUnit* enemy = NULL;
+
+ float3 pos;
+
+ if (lua_gettop(L) >= 5) {
+ pos.x = luaL_optnumber(L, 3, 0.0f);
+ pos.y = luaL_optnumber(L, 4, 0.0f);
+ pos.z = luaL_optnumber(L, 5, 0.0f);
+ } else {
+ enemy = ParseUnit(L, __FUNCTION__, 3);
+ }
+
+ lua_pushboolean(L, weapon->TestRange(pos, true, enemy));
+ return 1;
+}
+
+
+int LuaSyncedRead::GetUnitWeaponHaveFreeLineOfFire(lua_State* L)
+{
+ CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
+ if (unit == NULL) {
+ return 0;
+ }
+ const int weaponNum = luaL_checkint(L, 2);
+ if ((weaponNum < 0) || ((size_t)weaponNum >= unit->weapons.size())) {
+ return 0;
+ }
+
+ const CWeapon* weapon = unit->weapons[weaponNum];
+ const CUnit* enemy = NULL;
+
+ float3 pos;
+
+ if (lua_gettop(L) >= 5) {
+ pos.x = luaL_optnumber(L, 3, 0.0f);
+ pos.y = luaL_optnumber(L, 4, 0.0f);
+ pos.z = luaL_optnumber(L, 5, 0.0f);
+ } else {
+ enemy = ParseUnit(L, __FUNCTION__, 3);
+ }
+
+ lua_pushboolean(L, weapon->HaveFreeLineOfFire(pos, true, enemy));
+ return 1;
+}
+
+
+
int LuaSyncedRead::GetUnitTravel(lua_State* L)
{
CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
@@ -5245,81 +5331,6 @@ int LuaSyncedRead::GetUnitScriptNames(lua_State* L)
/******************************************************************************/
/******************************************************************************/
-int LuaSyncedRead::WeaponTryTarget(lua_State* L)
-{
- const CUnit* attacker = ParseUnit(L, __FUNCTION__, 1);
- const CUnit* attackee = ParseUnit(L, __FUNCTION__, 2);
-
- if (attacker == NULL)
- return 0;
-
- const unsigned int weaponID = luaL_checkint(L, 3);
- const float3 targetPos = float3(luaL_checkfloat(L, 4), luaL_checkfloat(L, 5), luaL_checkfloat(L, 6));
-
- if (weaponID >= attacker->weapons.size())
- return 0;
-
- lua_pushboolean(L, attacker->weapons[weaponID]->TryTarget(targetPos, false, attackee));
- return 1;
-}
-
-int LuaSyncedRead::WeaponTestTarget(lua_State* L)
-{
- const CUnit* attacker = ParseUnit(L, __FUNCTION__, 1);
- const CUnit* attackee = ParseUnit(L, __FUNCTION__, 2);
-
- if (attacker == NULL)
- return 0;
-
- const unsigned int weaponID = luaL_checkint(L, 3);
- const float3 targetPos = float3(luaL_checkfloat(L, 4), luaL_checkfloat(L, 5), luaL_checkfloat(L, 6));
-
- if (weaponID >= attacker->weapons.size())
- return 0;
-
- lua_pushboolean(L, attacker->weapons[weaponID]->TestTarget(targetPos, false, attackee));
- return 1;
-}
-
-int LuaSyncedRead::WeaponTestRange(lua_State* L)
-{
- const CUnit* attacker = ParseUnit(L, __FUNCTION__, 1);
- const CUnit* attackee = ParseUnit(L, __FUNCTION__, 2);
-
- if (attacker == NULL)
- return 0;
-
- const unsigned int weaponID = luaL_checkint(L, 3);
- const float3 targetPos = float3(luaL_checkfloat(L, 4), luaL_checkfloat(L, 5), luaL_checkfloat(L, 6));
-
- if (weaponID >= attacker->weapons.size())
- return 0;
-
- lua_pushboolean(L, attacker->weapons[weaponID]->TestRange(targetPos, false, attackee));
- return 1;
-}
-
-int LuaSyncedRead::WeaponHaveFreeLineOfFire(lua_State* L)
-{
- const CUnit* attacker = ParseUnit(L, __FUNCTION__, 1);
- const CUnit* attackee = ParseUnit(L, __FUNCTION__, 2);
-
- if (attacker == NULL)
- return 0;
-
- const unsigned int weaponID = luaL_checkint(L, 3);
- const float3 targetPos = float3(luaL_checkfloat(L, 4), luaL_checkfloat(L, 5), luaL_checkfloat(L, 6));
-
- if (weaponID >= attacker->weapons.size())
- return 0;
-
- lua_pushboolean(L, attacker->weapons[weaponID]->HaveFreeLineOfFire(targetPos, false, attackee));
- return 1;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-
int LuaSyncedRead::GetCOBUnitVar(lua_State* L)
{
CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
View
8 rts/Lua/LuaSyncedRead.h
@@ -128,6 +128,9 @@ class LuaSyncedRead {
static int GetUnitWeaponState(lua_State* L);
static int GetUnitWeaponVectors(lua_State* L);
static int GetUnitWeaponTryTarget(lua_State* L);
+ static int GetUnitWeaponTestTarget(lua_State* L);
+ static int GetUnitWeaponTestRange(lua_State* L);
+ static int GetUnitWeaponHaveFreeLineOfFire(lua_State* L);
static int GetUnitTravel(lua_State* L);
static int GetUnitFuel(lua_State* L);
static int GetUnitEstimatedPath(lua_State* L);
@@ -214,11 +217,6 @@ class LuaSyncedRead {
static int GetUnitScriptPiece(lua_State* L);
static int GetUnitScriptNames(lua_State* L);
- static int WeaponTryTarget(lua_State* L);
- static int WeaponTestTarget(lua_State* L);
- static int WeaponTestRange(lua_State* L);
- static int WeaponHaveFreeLineOfFire(lua_State* L);
-
static int TraceRay(lua_State* L); // not implemented
static int TraceRayUnits(lua_State* L); // not implemented
static int TraceRayFeatures(lua_State* L); // not implemented
View
2  rts/Lua/LuaUnitDefs.cpp
@@ -918,7 +918,7 @@ ADD_BOOL("canAttackWater", canAttackWater); // CUSTOM
ADD_FLOAT("nanoColorB", ud.nanoColor.z);
ADD_STRING("scriptName", ud.scriptName);
- ADD_STRING("scriptPath", ud.scriptName); // backward compability
+ ADD_STRING("scriptPath", ud.scriptName); //FIXME // backward compability
return true;
}
View
12 rts/Rendering/GL/VBO.cpp
@@ -12,6 +12,7 @@
#include "Rendering/GlobalRendering.h"
#include "System/Config/ConfigHandler.h"
+#include "System/Log/ILog.h"
CONFIG(bool, UseVBO).defaultValue(true).safemodeValue(false);
CONFIG(bool, UsePBO).defaultValue(true).safemodeValue(false);
@@ -134,8 +135,19 @@ void VBO::Resize(GLsizeiptr _size, GLenum usage, const void* data_)
size = _size;
if (VBOused) {
+ glClearErrors();
+
this->usage = usage;
glBufferData(curBoundTarget, size, data_, usage);
+
+ const GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ LOG_L(L_ERROR, "VBO/PBO: out of memory");
+ Unbind();
+ VBOused = false;
+ Bind(curBoundTarget);
+ Resize(_size, usage, data_);
+ }
} else {
delete[] data;
data = NULL; // to prevent a dead-pointer in case of an out-of-memory exception on the next line
View
17 rts/Rendering/Models/3DModel.cpp
@@ -76,6 +76,7 @@ S3DModelPiece::S3DModelPiece()
, colvol(NULL)
, type(MODELTYPE_OTHER)
, isEmpty(true)
+ , mIsIdentity(true)
, dispListID(0)
{
}
@@ -99,10 +100,11 @@ unsigned int S3DModelPiece::CreateDrawForList() const
void S3DModelPiece::DrawStatic() const
{
- const bool transform = (offset.SqLength() != 0.0f);
+ const bool transform = (offset.SqLength() != 0.0f || !mIsIdentity);
if (transform) {
glPushMatrix();
+ if (!mIsIdentity) glMultMatrixf(scaleRotMatrix);
glTranslatef(offset.x, offset.y, offset.z);
}
@@ -219,17 +221,18 @@ LocalModelPiece::~LocalModelPiece() {
bool LocalModelPiece::UpdateMatrix()
{
- bool r = true;
+ bool r = original->mIsIdentity;
{
- pieceSpaceMat.LoadIdentity();
+ // Assimp's Matrix: M = T * R * S; (SRT vs. RT in spring)
+ // else it's identity
+ pieceSpaceMat = original->scaleRotMatrix;
// Translate & Rotate are faster than matrix-mul!
- if (original->scale.SqLength() != 0.0f) { pieceSpaceMat.Scale(original->scale); r = false; }
if (pos.SqLength() != 0.0f) { pieceSpaceMat.Translate(pos); r = false; }
- if ( rot.y != 0.0f) { pieceSpaceMat.RotateY(-rot.y); r = false; }
- if ( rot.x != 0.0f) { pieceSpaceMat.RotateX(-rot.x); r = false; }
- if ( rot.z != 0.0f) { pieceSpaceMat.RotateZ(-rot.z); r = false; }
+ if ( rot.y != 0.0f) { pieceSpaceMat.RotateY(-rot.y); r = false; } // yaw
+ if ( rot.x != 0.0f) { pieceSpaceMat.RotateX(-rot.x); r = false; } // pitch
+ if ( rot.z != 0.0f) { pieceSpaceMat.RotateZ(-rot.z); r = false; } // roll
}
return r;
View
17 rts/Rendering/Models/3DModel.h
@@ -67,20 +67,25 @@ struct S3DModelPiece {
public:
std::string name;
std::string parentName;
- std::vector<S3DModelPiece*> children;
S3DModelPiece* parent;
CollisionVolume* colvol;
ModelType type;
- bool isEmpty;
+ bool isEmpty; /// if piece has no geometry
+ bool mIsIdentity; /// if scaleRotMatrix is identity
+
+ std::vector<S3DModelPiece*> children;
+
+ /// pre-baked local-space transforms (assimp-only)
+ CMatrix44f scaleRotMatrix;
+
+ float3 rot;
+ float3 offset; /// local offset wrt. parent piece
+ float3 goffset; /// global offset wrt. root piece
float3 mins;
float3 maxs;
- float3 offset; ///< @see parent
- float3 goffset; ///< @see root
- float3 rot;
- float3 scale;
protected:
virtual void DrawForList() const = 0;
View
133 rts/Rendering/Models/AssParser.cpp
@@ -51,36 +51,23 @@ static const int ASS_POSTPROCESS_OPTIONS =
| aiProcess_SplitLargeMeshes;
-// Convert Assimp quaternion to radians around x, y and z
-static float3 QuaternionToRadianAngles(aiQuaternion q1)
+static inline float3 aiVectorToFloat3(const aiVector3D v)
{
- float sqw = q1.w*q1.w;
- float sqx = q1.x*q1.x;
- float sqy = q1.y*q1.y;
- float sqz = q1.z*q1.z;
- float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
- float test = q1.x*q1.y + q1.z*q1.w;
-
- float3 result;
-
- if (test > 0.499f * unit) { // singularity at north pole
- result.x = 2 * math::atan2(q1.x,q1.w);
- result.y = PI/2;
- } else if (test < -0.499f * unit) { // singularity at south pole
- result.x = -2 * math::atan2(q1.x,q1.w);
- result.y = -PI/2;
- } else {
- result.x = math::atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw);
- result.y = math::asin(2*test/unit);
- result.z = math::atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw);
- }
- return result;
+ return float3(v.x, v.y, v.z);
}
-static inline float3 aiVectorToFloat3(const aiVector3D v)
+static inline CMatrix44f aiMatrixToMatrix(const aiMatrix4x4t<float>& m)
{
- return float3(v.x, v.y, v.z);
+ CMatrix44f n;
+
+ // assimp uses row-major, spring column-major, transform it
+ n[0] = m.a1; n[4] = m.a2; n[8 ] = m.a3; n[12] = m.a4;
+ n[1] = m.b1; n[5] = m.b2; n[9 ] = m.b3; n[13] = m.b4;
+ n[2] = m.c1; n[6] = m.c2; n[10] = m.c3; n[14] = m.c4;
+ n[3] = m.d1; n[7] = m.d2; n[11] = m.d3; n[15] = m.d4;
+
+ return n;
}
@@ -226,48 +213,66 @@ void CAssParser::CalculatePerMeshMinMax(SAssModel* model)
void CAssParser::LoadPieceTransformations(const S3DModel* model, SAssPiece* piece, const LuaTable& pieceMetaTable)
{
- //! Process transforms
- float3 rotate, scale, offset;
+ // Process transforms
+ float3 rotate, offset;
+ float3 scale(1.0,1.0,1.0);
aiVector3D _scale, _offset;
aiQuaternion _rotate;
piece->node->mTransformation.Decompose(_scale,_rotate,_offset);
+ const aiMatrix4x4t<float> aiRotMatrix = aiMatrix4x4t<float>(_rotate.GetMatrix());
LOG_S(LOG_SECTION_PIECE,
- "(%d:%s) Assimp offset (%f,%f,%f), rotate (%f,%f,%f), scale (%f,%f,%f)",
- model->numPieces, piece->name.c_str(),
- _offset.x, _offset.y, _offset.z,
- _rotate.x, _rotate.y, _rotate.z,
- _scale.x, _scale.y, _scale.z
- );
+ "(%d:%s) Assimp offset (%f,%f,%f), rotate (%f,%f,%f,%f), scale (%f,%f,%f)",
+ model->numPieces, piece->name.c_str(),
+ _offset.x, _offset.y, _offset.z,
+ _rotate.w, _rotate.x, _rotate.y, _rotate.z,
+ _scale.x, _scale.y, _scale.z
+ );
+
+ // Scale
+ scale = pieceMetaTable.GetFloat3("scale", float3(_scale.x, _scale.z, _scale.y));
+ scale.x = pieceMetaTable.GetFloat("scalex", scale.x);
+ scale.y = pieceMetaTable.GetFloat("scaley", scale.y);
+ scale.z = pieceMetaTable.GetFloat("scalez", scale.z);
- offset = pieceMetaTable.GetFloat3("offset", float3(_offset.x, _offset.y, _offset.z));
- offset.x = pieceMetaTable.GetFloat("offsetx", offset.x);
- offset.y = pieceMetaTable.GetFloat("offsety", offset.y);
- offset.z = pieceMetaTable.GetFloat("offsetz", offset.z);
+ if (scale.x != scale.y || scale.y != scale.z) {
+ //LOG_SL(LOG_SECTION_MODEL, L_WARNING, "Spring doesn't support non-uniform scaling");
+ scale.y = scale.x;
+ scale.z = scale.x;
+ }
- rotate = QuaternionToRadianAngles(_rotate);
- rotate = float3(rotate.z, rotate.x, rotate.y); // swizzle
- rotate = pieceMetaTable.GetFloat3("rotate", rotate * RADTODEG);
+ // Rotate
+ // Note these rotations are put into the `Spring rotations` and are not baked into the Assimp matrix!
+ rotate = pieceMetaTable.GetFloat3("rotate", float3(0,0,0));
rotate.x = pieceMetaTable.GetFloat("rotatex", rotate.x);
rotate.y = pieceMetaTable.GetFloat("rotatey", rotate.y);
rotate.z = pieceMetaTable.GetFloat("rotatez", rotate.z);
rotate *= DEGTORAD;
- scale = pieceMetaTable.GetFloat3("scale", float3(_scale.x, _scale.z, _scale.y));
- scale.x = pieceMetaTable.GetFloat("scalex", scale.x);
- scale.y = pieceMetaTable.GetFloat("scaley", scale.y);
- scale.z = pieceMetaTable.GetFloat("scalez", scale.z);
+ // Translate
+ offset = pieceMetaTable.GetFloat3("offset", float3(_offset.x, _offset.y, _offset.z));
+ offset.x = pieceMetaTable.GetFloat("offsetx", offset.x);
+ offset.y = pieceMetaTable.GetFloat("offsety", offset.y);
+ offset.z = pieceMetaTable.GetFloat("offsetz", offset.z);
LOG_S(LOG_SECTION_PIECE,
- "(%d:%s) Relative offset (%f,%f,%f), rotate (%f,%f,%f), scale (%f,%f,%f)",
- model->numPieces, piece->name.c_str(),
- offset.x, offset.y, offset.z,
- rotate.x, rotate.y, rotate.z,
- scale.x, scale.y, scale.z
- );
+ "(%d:%s) Relative offset (%f,%f,%f), rotate (%f,%f,%f), scale (%f,%f,%f)",
+ model->numPieces, piece->name.c_str(),
+ offset.x, offset.y, offset.z,
+ rotate.x, rotate.y, rotate.z,
+ scale.x, scale.y, scale.z
+ );
+
+ // construct 'baked' part of the modelpiece matrix
+ // Assimp order is: translate * rotate * scale * v
+ piece->scaleRotMatrix.LoadIdentity();
+ piece->scaleRotMatrix.Scale(scale);
+ piece->scaleRotMatrix *= aiMatrixToMatrix(aiRotMatrix);
+ // piece->scaleRotMatrix.Translate(offset);
+
piece->offset = offset;
piece->rot = rotate;
- piece->scale = scale;
+ piece->mIsIdentity = (scale.x == 1.0f) && aiRotMatrix.IsIdentity();
}
@@ -287,7 +292,7 @@ SAssPiece* CAssParser::LoadPiece(SAssModel* model, aiNode* node, const LuaTable&
piece->name = "root"; //! The real model root
}
- //! find a new name if none given or if a piece with the same name already exists
+ // find a new name if none given or if a piece with the same name already exists
if (piece->name.empty()) {
piece->name = "piece";
}
@@ -312,10 +317,10 @@ SAssPiece* CAssParser::LoadPiece(SAssModel* model, aiNode* node, const LuaTable&
piece->name.c_str());
}
- //! Load transforms
+ // Load transforms
LoadPieceTransformations(model, piece, pieceTable);
- //! Update piece min/max extents
+ // Update piece min/max extents
for (unsigned meshListIndex = 0; meshListIndex < node->mNumMeshes; meshListIndex++) {
const unsigned int meshIndex = node->mMeshes[meshListIndex];
const SAssModel::MinMax& minmax = model->mesh_minmax[meshIndex];
@@ -340,15 +345,17 @@ SAssPiece* CAssParser::LoadPiece(SAssModel* model, aiNode* node, const LuaTable&
}
if (strcmp(node->mName.data, "SpringRadius") == 0) {
if (!metaTable.KeyExists("midpos")) {
- //FIXME the swizzle looks wrong, the vertex positions below aren't swizzled and work fine!
- model->relMidPos = float3(piece->offset.x, piece->offset.z, piece->offset.y); // Y and Z are swapped because this piece isn't rotated
+ model->relMidPos = piece->scaleRotMatrix.Mul(piece->offset);
LOG_S(LOG_SECTION_MODEL,
"Model midpos of (%f,%f,%f) set by special node 'SpringRadius'",
model->relMidPos.x, model->relMidPos.y, model->relMidPos.z);
}
if (!metaTable.KeyExists("radius")) {
if (piece->maxs.x <= 0.00001f) {
- model->radius = piece->scale.x; // the blender import script only sets the scale property
+ aiVector3D _scale, _offset;
+ aiQuaternion _rotate;
+ piece->node->mTransformation.Decompose(_scale,_rotate,_offset);
+ model->radius = aiVectorToFloat3(_scale).x; // the blender import script only sets the scale property
} else {
model->radius = piece->maxs.x; // use the transformed mesh extents
}
@@ -437,7 +444,11 @@ SAssPiece* CAssParser::LoadPiece(SAssModel* model, aiNode* node, const LuaTable&
piece->vertexDrawIndices.reserve(piece->vertexDrawIndices.size() + mesh->mNumFaces * 3);
for (unsigned faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) {
const aiFace& face = mesh->mFaces[faceIndex];
- assert(face.mNumIndices == 3);
+
+ // some models contain lines (mNumIndices == 2)
+ // we cannot render those (esp. they would need to be called in a 2nd drawcall)
+ if (face.mNumIndices != 3)
+ continue;
for (unsigned vertexListID = 0; vertexListID < face.mNumIndices; ++vertexListID) {
const unsigned int vertexFaceIdx = face.mIndices[vertexListID];
@@ -446,7 +457,7 @@ SAssPiece* CAssParser::LoadPiece(SAssModel* model, aiNode* node, const LuaTable&
}
}
}
-
+
piece->isEmpty = piece->vertices.empty();
//! Get parent name from metadata or model
@@ -519,9 +530,7 @@ void CAssParser::BuildPieceHierarchy(S3DModel* model)
void CAssParser::CalculateModelDimensions(S3DModel* model, S3DModelPiece* piece)
{
// cannot set this until parent relations are known, so either here or in BuildPieceHierarchy()
- piece->goffset = piece->offset + ((piece->parent != NULL)? piece->parent->goffset: ZeroVector);
-
- model->numPieces += 1;
+ piece->goffset = piece->scaleRotMatrix.Mul(piece->offset) + ((piece->parent != NULL)? piece->parent->goffset: ZeroVector);
// update model min/max extents
model->mins = std::min(piece->goffset + piece->mins, model->mins);
View
6 rts/Rendering/ProjectileDrawer.cpp
@@ -414,7 +414,7 @@ void CProjectileDrawer::DrawProjectiles(int modelType, int numFlyingPieces, int*
ProjectileBin& projectileBin = modelRenderers[modelType]->GetProjectileBinMutable();
for (ProjectileBinIt binIt = projectileBin.begin(); binIt != projectileBin.end(); ++binIt) {
- if (modelType == MODELTYPE_S3O) {
+ if (modelType != MODELTYPE_3DO) {
texturehandlerS3O->SetS3oTexture(binIt->first);
}
@@ -748,7 +748,7 @@ bool CProjectileDrawer::DrawProjectileModel(const CProjectile* p, bool shadowPas
if (p->weapon) {
// weapon-projectile
- const CWeaponProjectile* wp = dynamic_cast<const CWeaponProjectile*>(p);
+ const CWeaponProjectile* wp = static_cast<const CWeaponProjectile*>(p);
#define SET_TRANSFORM_VECTORS(dir) \
float3 rightdir, updir; \
@@ -818,7 +818,7 @@ bool CProjectileDrawer::DrawProjectileModel(const CProjectile* p, bool shadowPas
#undef TRANSFORM_DRAW
} else {
// piece-projectile
- const CPieceProjectile* pp = dynamic_cast<const CPieceProjectile*>(p);
+ const CPieceProjectile* pp = static_cast<const CPieceProjectile*>(p);
if (!shadowPass) {
unitDrawer->SetTeamColour(pp->GetTeamID());
View
12 rts/Sim/MoveTypes/GroundMoveType.cpp
@@ -2064,15 +2064,17 @@ void CGroundMoveType::KeepPointingTo(float3 pos, float distance, bool aggressive
float3 dir1 = frontWeapon->mainDir;
float3 dir2 = mainHeadingPos - owner->pos;
- dir1.y = 0.0f;
- dir1.Normalize();
- dir2.y = 0.0f;
- dir2.SafeNormalize();
+ // in this case aligning is impossible
+ if (dir1 == UpVector)
+ return;
+
+ dir1.y = 0.0f; dir1.SafeNormalize();
+ dir2.y = 0.0f; dir2.SafeNormalize();
if (dir2 == ZeroVector)
return;
- short heading =
+ const short heading =
GetHeadingFromVector(dir2.x, dir2.z) -
GetHeadingFromVector(dir1.x, dir1.z);
View
7 rts/System/Log/DefaultFormatter.cpp
@@ -56,9 +56,12 @@ static inline void PrintfAppend(char** buffer, size_t* bufferSize, const char* f
// So we need to make a copy, if want to run it again.
va_list arguments_;
va_copy(arguments_, arguments);
- VSNPRINTF(bufAppendPos, freeBufferSize, fmt, arguments_);
+ int writtenChars = VSNPRINTF(bufAppendPos, freeBufferSize, fmt, arguments_);
va_end(arguments_);
- const bool bufferTooSmall = ((strlen(*buffer) + 1) >= *bufferSize);
+ // since writtenChars excludes the null terminator (if any was written),
+ // writtenChars >= freeBufferSize always means buffer was too small
+ // NOTE: earlier glibc versions and MSVC will return -1 when buffer is too small
+ const bool bufferTooSmall = writtenChars >= freeBufferSize || writtenChars < 0;
if (!bufferTooSmall) break;
ResizeBuffer(buffer, bufferSize, true);
View
2  rts/System/SpringApp.cpp
@@ -1056,8 +1056,8 @@ void SpringApp::Shutdown()
GML::Exit();
SafeDelete(pregame);
SafeDelete(game);
- agui::FreeGui();
SafeDelete(selectMenu);
+ agui::FreeGui();
SafeDelete(net);
SafeDelete(gameServer);
SafeDelete(gameSetup);
View
2  rts/lib/gml/gml.cpp
@@ -60,7 +60,7 @@ int gmlNoGLThreadNum = GML_NO_THREAD_NUM;
volatile bool gmlMultiThreadSim = true;
volatile bool gmlStartSim = false;
volatile bool gmlKeepRunning = false;
-bool gmlServerActive = false;
+volatile bool gmlServerActive = false;
#define EXEC_RUN (BYTE *)NULL
#define EXEC_SYNC (BYTE *)-1
View
2  rts/lib/gml/gmlcls.h
@@ -36,7 +36,7 @@ extern bool gmlCheckCallChain;
extern int gmlCallChainWarning;
extern int gmlNextTickUpdate;
extern unsigned gmlCurrentTicks;
-extern bool gmlServerActive;
+extern volatile bool gmlServerActive;
#define GML_QUOTE(x) #x
Please sign in to comment.
Something went wrong with that request. Please try again.