Commit 2616e60e authored by rogerborg's avatar rogerborg

https://sourceforge.net/tracker2/?func=detail&aid=2473523&group_id=74339&atid=540676

Fix bug in dimension2d::operator+=.  Add operator-= and have operator == use core::equals() while I'm in there.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1984 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 2a3eb2c2
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __IRR_DIMENSION2D_H_INCLUDED__
#define __IRR_DIMENSION2D_H_INCLUDED__
#include "irrTypes.h"
namespace irr
{
namespace core
{
//! Specifies a 2 dimensional size.
template <class T>
class dimension2d
{
public:
//! Default constructor for empty dimension
dimension2d() : Width(0), Height(0) {}
//! Constructor with width and height
dimension2d(const T& width, const T& height)
: Width(width), Height(height) {}
//! Equality operator
bool operator==(const dimension2d<T>& other) const
{
return Width == other.Width && Height == other.Height;
}
//! Inequality operator
bool operator!=(const dimension2d<T>& other) const
{
return ! (*this == other);
}
//! Set to new values
dimension2d<T>& set(const T& width, const T& height)
{
Width = width;
Height = height;
return *this;
}
//! Divide width and height by scalar
dimension2d<T>& operator/=(const T& scale)
{
Width /= scale;
Height /= scale;
return *this;
}
//! Divide width and height by scalar
dimension2d<T> operator/(const T& scale) const
{
return dimension2d<T>(Width/scale, Height/scale);
}
//! Multiply width and height by scalar
dimension2d<T>& operator*=(const T& scale)
{
Width *= scale;
Height *= scale;
return *this;
}
//! Multiply width and height by scalar
dimension2d<T> operator*(const T& scale) const
{
return dimension2d<T>(Width*scale, Height*scale);
}
//! Add two dimensions
dimension2d<T>& operator+=(const dimension2d<T>& other)
{
Width *= other.Width;
Height *= other.Height;
return *this;
}
//! Add two dimensions
dimension2d<T> operator+(const dimension2d<T>& other) const
{
return dimension2d<T>(Width+other.Width, Height+other.Height);
}
//! Get area
T getArea() const
{
return Width*Height;
}
//! Get the optimal size according to some properties
/** This is a function often used for texture dimension
calculations. The function returns the next larger or
smaller dimension which is a power-of-two dimension
(2^n,2^m) and/or square (Width=Height).
\param requirePowerOfTwo Forces the result to use only
powers of two as values.
\param requireSquare Makes width==height in the result
\param larger Choose whether the result is larger or
smaller than the current dimension. If one dimension
need not be changed it is kept with any value of larger.
\return The optimal dimension under the given
constraints. */
dimension2d<T> getOptimalSize(
bool requirePowerOfTwo=true,
bool requireSquare=false,
bool larger=true) const
{
u32 i=1;
u32 j=1;
if (requirePowerOfTwo)
{
while (i<(u32)Width)
i<<=1;
if (!larger && i!=1 && i!=(u32)Width)
i>>=1;
while (j<(u32)Height)
j<<=1;
if (!larger && j!=1 && j!=(u32)Height)
j>>=1;
}
else
{
i=(u32)Width;
j=(u32)Height;
}
if (requireSquare)
{
if ((larger && (i>j)) || (!larger && (i<j)))
j=i;
else
i=j;
}
return dimension2d<T>((T)i,(T)j);
}
//! Get the interpolated dimension
/** \param other Other dimension to interpolate with.
\param d Value between 0.0f and 1.0f.
\return Interpolated dimension. */
dimension2d<T> getInterpolated(const dimension2d<T>& other, f32 d) const
{
T inv = (T) (1.0f - d);
return dimension2d<T>(other.Width*inv + Width*d, other.Height*inv + Height*d);
}
//! Width of the dimension.
T Width;
//! Height of the dimension.
T Height;
};
//! Typedef for an f32 dimension.
typedef dimension2d<f32> dimension2df;
//! Typedef for an integer dimension.
typedef dimension2d<s32> dimension2di;
} // end namespace core
} // end namespace irr
#endif
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __IRR_DIMENSION2D_H_INCLUDED__
#define __IRR_DIMENSION2D_H_INCLUDED__
#include "irrTypes.h"
#include "irrMath.h" // for irr::core::equals()
namespace irr
{
namespace core
{
//! Specifies a 2 dimensional size.
template <class T>
class dimension2d
{
public:
//! Default constructor for empty dimension
dimension2d() : Width(0), Height(0) {}
//! Constructor with width and height
dimension2d(const T& width, const T& height)
: Width(width), Height(height) {}
//! Equality operator
bool operator==(const dimension2d<T>& other) const
{
return core::equals(Width, other.Width) &&
core::equals(Height, other.Height);
}
//! Inequality operator
bool operator!=(const dimension2d<T>& other) const
{
return ! (*this == other);
}
//! Set to new values
dimension2d<T>& set(const T& width, const T& height)
{
Width = width;
Height = height;
return *this;
}
//! Divide width and height by scalar
dimension2d<T>& operator/=(const T& scale)
{
Width /= scale;
Height /= scale;
return *this;
}
//! Divide width and height by scalar
dimension2d<T> operator/(const T& scale) const
{
return dimension2d<T>(Width/scale, Height/scale);
}
//! Multiply width and height by scalar
dimension2d<T>& operator*=(const T& scale)
{
Width *= scale;
Height *= scale;
return *this;
}
//! Multiply width and height by scalar
dimension2d<T> operator*(const T& scale) const
{
return dimension2d<T>(Width*scale, Height*scale);
}
//! Add another dimension to this one.
dimension2d<T>& operator+=(const dimension2d<T>& other)
{
Width += other.Width;
Height += other.Height;
return *this;
}
//! Subtract a dimension from this one
dimension2d<T>& operator-=(const dimension2d<T>& other)
{
Width -= other.Width;
Height -= other.Height;
return *this;
}
//! Add two dimensions
dimension2d<T> operator+(const dimension2d<T>& other) const
{
return dimension2d<T>(Width+other.Width, Height+other.Height);
}
//! Get area
T getArea() const
{
return Width*Height;
}
//! Get the optimal size according to some properties
/** This is a function often used for texture dimension
calculations. The function returns the next larger or
smaller dimension which is a power-of-two dimension
(2^n,2^m) and/or square (Width=Height).
\param requirePowerOfTwo Forces the result to use only
powers of two as values.
\param requireSquare Makes width==height in the result
\param larger Choose whether the result is larger or
smaller than the current dimension. If one dimension
need not be changed it is kept with any value of larger.
\return The optimal dimension under the given
constraints. */
dimension2d<T> getOptimalSize(
bool requirePowerOfTwo=true,
bool requireSquare=false,
bool larger=true) const
{
u32 i=1;
u32 j=1;
if (requirePowerOfTwo)
{
while (i<(u32)Width)
i<<=1;
if (!larger && i!=1 && i!=(u32)Width)
i>>=1;
while (j<(u32)Height)
j<<=1;
if (!larger && j!=1 && j!=(u32)Height)
j>>=1;
}
else
{
i=(u32)Width;
j=(u32)Height;
}
if (requireSquare)
{
if ((larger && (i>j)) || (!larger && (i<j)))
j=i;
else
i=j;
}
return dimension2d<T>((T)i,(T)j);
}
//! Get the interpolated dimension
/** \param other Other dimension to interpolate with.
\param d Value between 0.0f and 1.0f.
\return Interpolated dimension. */
dimension2d<T> getInterpolated(const dimension2d<T>& other, f32 d) const
{
T inv = (T) (1.0f - d);
return dimension2d<T>(other.Width*inv + Width*d, other.Height*inv + Height*d);
}
//! Width of the dimension.
T Width;
//! Height of the dimension.
T Height;
};
//! Typedef for an f32 dimension.
typedef dimension2d<f32> dimension2df;
//! Typedef for an integer dimension.
typedef dimension2d<s32> dimension2di;
} // end namespace core
} // end namespace irr
#endif
// This is the entry point for the Irrlicht test suite.
#define _CRT_SECURE_NO_WARNINGS
#include "testUtils.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <vector>
// This is an MSVC pragma to link against the Irrlicht library.
// Other builds must link against it in the project files.
#if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib")
#endif // _MSC_VER
typedef struct _STestDefinition
{
bool(*testSignature)(void);
const char * testName;
} STestDefinition;
//! This is the main entry point for the Irrlicht test suite.
/** \return The number of test that failed, i.e. 0 is success. */
int main(int argumentCount, char * arguments[])
{
bool logFileOpened = openTestLog(1 == argumentCount);
assert(logFileOpened);
if(argumentCount > 3)
{
logTestString("\nUsage: %s [testNumber] [totalFails]\n");
closeTestLog();
return 9999;
}
#define TEST(x)\
{\
extern bool x(void);\
STestDefinition newTest;\
newTest.testSignature = x;\
newTest.testName = #x;\
tests.push_back(newTest);\
}
std::vector<STestDefinition> tests;
// Note that to interactively debug a test, you will generally want to move it
// (temporarily) to the beginning of the list, since each test runs in its own
// process.
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
TEST(sceneNodeAnimator);
TEST(sceneCollisionManager);
TEST(collisionResponseAnimator);
TEST(exports);
TEST(testVector3d);
TEST(testVector2d);
TEST(planeMatrix);
TEST(fast_atof);
TEST(line2dIntersectWith);
TEST(drawPixel);
TEST(md2Animation);
TEST(guiDisabledMenu);
TEST(softwareDevice);
TEST(b3dAnimation);
const unsigned int numberOfTests = tests.size();
unsigned int testToRun = 0;
unsigned int fails = 0;
if(argumentCount > 1)
{
testToRun = (unsigned int)atoi(arguments[1]);
if(testToRun >= numberOfTests)
{
logTestString("\nError: invalid test %d (maximum %d)\n",
testToRun, numberOfTests - 1);
closeTestLog();
return 9999;
}
}
if(argumentCount > 2)
fails = (unsigned int)atoi(arguments[2]);
logTestString("\nStarting test %d, '%s'\n",
testToRun, tests[testToRun].testName);
bool success = tests[testToRun].testSignature();
if(!success)
{
logTestString("\n\n\n******** Test failure ********\nTest %d '%s' failed\n"\
"******** Test failure ********\n",
testToRun, tests[testToRun].testName);
fails++;
}
testToRun++;
if(testToRun < numberOfTests)
{
closeTestLog();
char runNextTest[256];
(void)sprintf(runNextTest, "%s %d %d", arguments[0], testToRun, fails);
fails = system(runNextTest);
}
if(1 == testToRun)
{
(void)openTestLog(false);
const int passed = numberOfTests - fails;
logTestString("\nTests finished. %d test%s of %d passed.\n",
passed, 1 == passed ? "" : "s", numberOfTests);
if(0 == fails)
{
time_t rawtime;
struct tm * timeinfo;
(void)time(&rawtime);
timeinfo = gmtime(&rawtime);
(void)printf("\nTest suite pass at GMT %s\n", asctime(timeinfo));
FILE * testsLastPassedAtFile = fopen("tests-last-passed-at.txt", "w");
if(testsLastPassedAtFile)
{
(void)fprintf(testsLastPassedAtFile, "Test suite pass at GMT %s\n", asctime(timeinfo));
(void)fclose(testsLastPassedAtFile);
}
}
closeTestLog();
}
return fails;
}
// This is the entry point for the Irrlicht test suite.
#define _CRT_SECURE_NO_WARNINGS
#include "testUtils.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <vector>
// This is an MSVC pragma to link against the Irrlicht library.
// Other builds must link against it in the project files.
#if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib")
#endif // _MSC_VER
typedef struct _STestDefinition
{
bool(*testSignature)(void);
const char * testName;
} STestDefinition;
//! This is the main entry point for the Irrlicht test suite.
/** \return The number of test that failed, i.e. 0 is success. */
int main(int argumentCount, char * arguments[])
{
bool logFileOpened = openTestLog(1 == argumentCount);
assert(logFileOpened);
if(argumentCount > 3)
{
logTestString("\nUsage: %s [testNumber] [totalFails]\n");
closeTestLog();
return 9999;
}
#define TEST(x)\
{\
extern bool x(void);\
STestDefinition newTest;\
newTest.testSignature = x;\
newTest.testName = #x;\
tests.push_back(newTest);\
}
std::vector<STestDefinition> tests;
// Note that to interactively debug a test, you will generally want to move it
// (temporarily) to the beginning of the list, since each test runs in its own
// process.
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
TEST(sceneNodeAnimator);
TEST(sceneCollisionManager);
TEST(collisionResponseAnimator);
TEST(exports);
TEST(testVector3d);
TEST(testVector2d);
TEST(planeMatrix);
TEST(fast_atof);
TEST(line2dIntersectWith);
TEST(testDimension2d);
TEST(drawPixel);
TEST(md2Animation);
TEST(guiDisabledMenu);
TEST(softwareDevice);
TEST(b3dAnimation);
const unsigned int numberOfTests = tests.size();
unsigned int testToRun = 0;
unsigned int fails = 0;
if(argumentCount > 1)
{
testToRun = (unsigned int)atoi(arguments[1]);
if(testToRun >= numberOfTests)
{
logTestString("\nError: invalid test %d (maximum %d)\n",
testToRun, numberOfTests - 1);
closeTestLog();
return 9999;
}
}
if(argumentCount > 2)
fails = (unsigned int)atoi(arguments[2]);
logTestString("\nStarting test %d, '%s'\n",
testToRun, tests[testToRun].testName);
bool success = tests[testToRun].testSignature();
if(!success)
{
logTestString("\n\n\n******** Test failure ********\nTest %d '%s' failed\n"\
"******** Test failure ********\n",
testToRun, tests[testToRun].testName);
fails++;
}
testToRun++;
if(testToRun < numberOfTests)
{
closeTestLog();
char runNextTest[256];
(void)sprintf(runNextTest, "%s %d %d", arguments[0], testToRun, fails);
fails = system(runNextTest);
}
if(1 == testToRun)
{
(void)openTestLog(false);
const int passed = numberOfTests - fails;
logTestString("\nTests finished. %d test%s of %d passed.\n",
passed, 1 == passed ? "" : "s", numberOfTests);
if(0 == fails)
{
time_t rawtime;
struct tm * timeinfo;
(void)time(&rawtime);
timeinfo = gmtime(&rawtime);
(void)printf("\nTest suite pass at GMT %s\n", asctime(timeinfo));
FILE * testsLastPassedAtFile = fopen("tests-last-passed-at.txt", "w");
if(testsLastPassedAtFile)
{
(void)fprintf(testsLastPassedAtFile, "Test suite pass at GMT %s\n", asctime(timeinfo));
(void)fclose(testsLastPassedAtFile);
}
}
closeTestLog();
}
return fails;
}
// Copyright (C) 2008 Colin MacDonald
// No rights reserved: this software is in the public domain.
#include "testUtils.h"
#include "irrlicht.h"
#include <assert.h>
using namespace irr;
using namespace core;
/** Some very basic testing of dimension2df:
operator+=
operator!= (and thus implicitly operator==) */
bool testDimension2d(void)
{
dimension2df dimension(100.f, 100.f);
const dimension2df addDimension(200.f, -200.f);
(void)(dimension += addDimension);
if(dimension != dimension2df(300.f, -100.f))
{
logTestString("dimension2df != produced unexpected result.\n");
assert(false);
return false;
}
(void)(dimension -= addDimension);
if(dimension != dimension2df(100.f, 100.f))
{
logTestString("dimension2df -= produced unexpected result.\n");
assert(false);
return false;
}
return true;
}
......@@ -51,6 +51,7 @@
<Unit filename="sceneCollisionManager.cpp" />
<Unit filename="sceneNodeAnimator.cpp" />
<Unit filename="softwareDevice.cpp" />
<Unit filename="testDimension2d.cpp" />
<Unit filename="testUtils.cpp" />
<Unit filename="testVector2d.cpp" />
<Unit filename="testVector3d.cpp" />
......
......@@ -225,6 +225,10 @@
RelativePath=".\softwareDevice.cpp"
>
</File>
<File
RelativePath=".\testDimension2d.cpp"
>
</File>
<File
RelativePath=".\testUtils.cpp"
>
......
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
......@@ -221,6 +222,10 @@
RelativePath=".\softwareDevice.cpp"
>
</File>
<File
RelativePath=".\testDimension2d.cpp"
>
</File>
<File
RelativePath=".\testUtils.cpp"
>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment