Overloading * operator gives no match error - c++

Hi I am trying to create a ray tracer that renders a polygonized, triangle-based model.
I have a point 3D struct in point3d.h that holds x,y, and z coordinates.
#ifndef __POINT3D_H__
#define __POINT3D_H__
#include <iostream>
using namespace std;
struct Point3D
{
double x;
double y;
double z;
Point3D() : x(0.0), y(0.0), z(0.0) {}
Point3D(const double & nx, const double & ny, const double & nz) : x(nx), y(ny), z(nz) {}
Point3D operator+(const Point3D & rhs) const {
return Point3D(x + rhs.x, y + rhs.y, z + rhs.z); }
Point3D operator-(const Point3D & rhs) const {
return Point3D(x - rhs.x, y - rhs.y, z - rhs.z); }
Point3D operator*(double val) const {
return Point3D(x * val, y * val, z * val); }
Point3D operator/(double val) const {
return Point3D(x / val, y / val, z / val); }
Point3D operator+=(const Point3D & rhs) {
x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
Point3D operator-=(const Point3D & rhs) {
x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
Point3D operator*=(double val) {
x *= val; y *= val; z *= val; return *this; }
Point3D operator/=(double val) {
x /= val; y /= val; z /= val; return *this; }
void print() {
cout << '(' << x << ',' << y << ',' << z << ')';
}
};
#endif
Here is where I try to use the * operator to multiple two Point3Ds together
Point3D phong(Point3D mColor, Point3D lColor, Point3D L, Point3D N, Point3D R, Point3D V)
{
Point3D k(1.0, 1.0, 1.0);
Point3D ambient = mColor * k.x;
Point3D diffuse_angle = ((N * L) / (length(N) * length(L)));
Point3D diffuse = lColor * k.y * diffuse_angle;
Point3D specular_angle = ((R * V) / (length(R) * length(V)));
double specular_x = pow(specular_angle.x, 100.0);
double specular_y = pow(specular_angle.y, 100.0);
double specular_z = pow(specular_angle.z, 100.0);
Point3D specular_power(specular_x, specular_y, specular_z);
Point3D specular = lColor * k.z * specular_power;
return ambient + (lColor * (diffuse + specular));
}
When I try to multiple two Point3D's together, I am getting a no match error.
Here is where the code fails. I feel like it is a simple mistake but I cannot figure it out. I am including the Point3d header file as follows: #include "point3d.h".

Point3D operator*(double val) const
You have just this version, Point3D * double and nothing else, but you are trying to use this operator for Point3D * Point3D. Point3D is not implicitly constructible from double, so this is why you have compilation error.

Point3D operator*(double val) const {
This is for multiplication Point3D * double. And by
N * L
you are trying to do Point3D * Point3D.
You can rectify this either by providing proper operator* for your class OR provide a conversion from double to your class through single argument constructor. Although I prefer former.

You should need a function like this
Point3D operator *(Point3D &temp) const {
}
Since you don't have function to multiply two 3d points you are getting errors.Try adding this function.

You need a function for the operation Point3D * Point3D, which can't be adapted for the call of Point3D::operator*(double val). Such as:
Point3D operator*(const Point3D & rhs) const {
return Point3D(x * rhs.x, y * rhs.y, z * rhs.z); }

Related

Basic Shading in C++ to a BMP image. Facing ratio calculation

I am studying Shading and how light interacts with objects. I found a great website and wanted to implement knowledge from https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/shading-normals in my own way.
I wrote a code. It is supposed to calculate a facing ratio (cosine of the angle between a normal vector and a light Ray ) and generate a ".BMP" image with that. I took a surface as an object (well, on the image it will be a circle). The idea was to calculate the effect of this ratio on the color of the surface, i.e how light and object interact.
The code is as follows
template <typename T>
class Vec3
{
private:
T x, y, z;
public:
Vec3(): x{0},y{0},z{0} {}
Vec3(T xx): x{xx}, y{xx},z{xx} {}
Vec3(T xx, T yy, T zz): x{xx}, y{yy}, z{zz} {}
friend Vec3<T> operator+(const Vec3<T>& vec1, const Vec3<T>& vec2) { return Vec3<T>(vec1.x + vec2.x, vec1.y + vec2.y, vec1.z + vec2.z); }
friend Vec3<T> operator-(const Vec3<T>& vec1, const Vec3<T>& vec2) { return Vec3<T>(vec1.x - vec2.x, vec1.y - vec2.y, vec1.z - vec2.z); }
friend Vec3<T> operator*(const Vec3<T>& vec1, const Vec3<T>& vec2) { return Vec3<T>(vec1.x * vec2.x, vec1.y * vec2.y, vec1.z * vec2.z); }
friend Vec3<T> operator*(const Vec3<T>& vec1, const T& k) { return Vec3<T>(vec1.x * k, vec1.y * k, vec1.z * k); }
friend Vec3<T> operator/(const Vec3<T>& vec1, const T& k) { return Vec3<T>(vec1.x / k, vec1.y / k, vec1.z / k); }
Vec3<T> operator - () const { return Vec3<T>(-x, -y, -z); }
T dot (const Vec3<T>& v) const { return x * v.x + y * v.y + z * v.z; }
T lengthWithoutRoot() const { return x * x + y * y + z * z; }
T length() const { return sqrt(lengthWithoutRoot()); }
Vec3& normalize()
{
T nor2 = lengthWithoutRoot();
if (nor2 > 0) {
T divider = 1 / sqrt(nor2);
x *= divider, y *= divider, z *= divider;
}
return *this;
}
Vec3<T> reflection(const Vec3<T>& prim,const Vec3<T>& normal) // TO BE CHECKED
{
Vec3<T> reflection = prim - 2 * (prim.dot(normal)) * normal;
return reflection;
}
friend std::ostream& operator<<(std::ostream &out, const Vec3<T>& vec)
{
out << '(' << vec.x << ',' << vec.y << ',' << vec.z << ')';
return out;
}
const T& getX() { return x; }
const T& getY() { return y; }
const T& getZ() { return z; }
};
typedef Vec3<float> Vec3f;
class Sphere
{
private:
Vec3f center;
float radius;
public:
Sphere(const Vec3f& c, const float& r): center{c}, radius{r} {}
bool intersect(const Vec3f& primRay)
{
Vec3f vecRadius = center - primRay;
float distLength = vecRadius.length();
if (distLength > radius)
return false;
return true;
}
bool intersectSurface(const Vec3f& primRay)
{
Vec3f vecRadius = center - primRay;
float distLength = vecRadius.length();
if (distLength == radius)
return true;
return false;
}
float alphaPositive(const Vec3f& p, const Vec3f& source)
{
Vec3f primRay = (source-p).normalize();
Vec3f normal = (p-center).normalize();
float diff = primRay.dot(normal);
return std::max(diff,0.f) ;
}
};
int main()
{
Sphere sphere (Vec3f{ 250.0f, 250.0f, 0.0 }, 150.0f );
Vec3f source{ 100,200,0.0 };
Vec3f color{ 255,255,255 };
std::ofstream file;
file.open("DIF_SPHERE36.ppm");
file << "P6\n" << height << " " << width << "\n255\n";
for (float h = 0; h < 500; ++h)
{
for (float w = 0; w < 500; ++w)
{
Vec3f primRay = { h,w,0.0 };
if (sphere.intersect(primRay))
{
float facingRatio= sphere.alphaPositive(primRay, source);
color = Vec3f{255,0,0}*facingRatio;
file << unsigned char(color.getX()) << unsigned char(color.getY()) << unsigned char(color.getZ());
}
else
file << unsigned char(255) << unsigned char(255) << unsigned char(255);
}
}
file.close();
return 0;
}
However. I get smth strange, even when I try to change 'source' coordinates.
Facing ratio is calculated in alphaPositive function This is what a code must generate according to the idea
Thank you all for your comments.
I made following conclusions:
In function alphaPositive I had to use return std::max(diff,0.1f) instead of return std::max(diff,0.f).
Had to change positioning of the Object and Light by adding z-coordinates.
With that I managed to get a sphere with some effects.

C++ function that can take integer or float or double or any other castable to float

I am trying to implement a Vector3 struct in C++. I am overloading the "*" operator for handling multiplication with the scalar values. So it will work like this:
v1 = Vector3(1.0f, 1.0f, 1.0f);
v2 = 2*v1;
v3 = 2.4f*v1;
v4 = 2.4*v1;
All 3 operations will return a Vector3 instance. However, I don't want to implement 3 functions for this purpose.
Vector3 operator * (int& const val) {
float _val = static_cast<float> (val);
return Vector3(x * _val, y * _val, z * _val);
}
Vector3 operator * (double& const val) {
float _val = static_cast<float> (val);
return Vector3(x * _val, y * _val, z * _val);
}
Vector3 operator * (float& const val) {
return Vector3(x * val, y * val, z * val);
}
Is there a better way of doing this with one function?
Since you are casting all of the types to float again, you don't need that.
If you defined your function to accept a float, then passed an int or any convertible type, it would be cast to float automatically. The following code shows that
#include <typeinfo>
#include <iostream>
struct Vector3
{
Vector3(float x, float y, float z): x{x}, y{y}, z{z}{}
float x, y, z;
Vector3 operator*(float val)const{
return Vector3{val * x,val * y,val * z};
}
};
int main(){
Vector3 v1{1,2,3};
auto v2 = v1*2;
std::cout << typeid(v2.x).name();
}
Live
If you want to use the multiplication in reverse order
#include <typeinfo>
#include <iostream>
struct Vector3
{
Vector3(float x, float y, float z): x{x}, y{y}, z{z}{}
float x, y, z;
};
Vector3 operator*(float val, const Vector3& v){
return Vector3{val * v.x,val * v.y,val * v.z};
}
int main(){
Vector3 v1{1,2,3};
auto v2 = 2*v1;
std::cout << typeid(v2.x).name();
}
I used public members for simplicity. u may want to use private ones with setters and getters.
If you really must use reference parameters and the float data type internally, and you wish to avoid compiler warnings about implicit conversions, then you can use a templated operator function (note also the modified position of the const qualifier):
template<typename T>
Vector3 operator * (const T& val)
{
float mul = static_cast<float>(val); // Change this to any specific conversion/cast you want
return Vector3(x * mul, y * mul, z * mul);
}
You will also need to use a Vector3 object as the first operand of the * operator:
int main()
{
Vector3 v1 = Vector3(1.0f, 1.0f, 1.0f);
// Vector3 v2 = 2 * v1;
// Vector3 v3 = 2.4f * v1; // These won't work!
// Vector3 v4 = 2.4 * v1;
Vector3 v2 = v1 * 2;
Vector3 v3 = v1 * 2.4f; // But these will
Vector3 v4 = v1 * 2.4;
return 0;
}
EDIT: If you want a 'commutative' operator (that is, one in which you could use the scalar operand in either position), then you can declare a friend operator that takes two arguments (the constant and a class reference):
template<typename T>
friend Vector3 operator * (const T& val, const Vector3& vec)
{
float mul = static_cast<float>(val); // Change this to any specific conversion/cast you want
return Vector3(vec.x * mul, vec.y * mul, vec.z * mul);
}
As I see, it's enough to define/declare variant with double and it will work with floats and integers as well.
Here is compilable example (just test & demonstration):
class Vector3 {
public:
Vector3(double x, double y, double z): x(x), y(y), z(z) { }
Vector3 operator * (double val) {
return Vector3(x * val,
y * val,
z * val);
}
private:
double x { 0 };
double y { 0 };
double z { 0 };
};
int main()
{
int a = 1;
float b = 2.1;
double c = 3.5;
Vector3 vec1(1, 2.1f, 3);
Vector3 vec2(a, b, c);
auto vec3 = vec1 * a;
auto vec4 = vec1 * b;
auto vec5 = vec1 * c;
return 0;
}

C++ Angle between two vectors with acos

I'm trying to get this code to work and it gives out angles but not the right ones though, they don't add up to 180° and I can't find the problem. I've implemented a Vector2 struct which resembles a two-dimensional Vector and I have been trying to define the ^ operator for it as the function to give the angles between the two vectors.
Thanks for the help in advance!
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
struct Vector2 {
double x, y;
};
ostream& operator<<(ostream& out, const Vector2& w){
cout << '[' << w.x << " , " << w.y << ']';
return out;
}
double operator*(const Vector2& a, const Vector2& b){
double w = a.x*b.x + a.y*b.y;
return w;
}
double absc(const Vector2& d) {
return sqrt(d*d);
}
constexpr Vector2 operator+(const Vector2& a, const Vector2& b){
Vector2 y{a.x+b.x, a.y+a.y};
return y;
}
constexpr Vector2 operator-(const Vector2& a,const Vector2& b){
Vector2 z{a.x-b.x, a.y-b.y};
return z;
}
double operator^(const Vector2& a,const Vector2& b){
double n = (absc(a))*(absc(b));
double c = acos((a*b)/n);
return c;
}
int main(){
Vector2 a = {1.0, 1.0};
Vector2 b = {4.0, 7.0};
Vector2 c = {-2.0, 5.0};
double d =c^b;
double e = a^c;
double f = a^b;
auto grad = [](double rad) { return rad * (45./atan(1.0)); };
cout<<"Angle Alpha: "<<grad(c^b)<<"rad "<<d<<"\n";
cout<<"Angle Beta: "<<grad(a^c)<<"rad "<<e<<"\n";
cout<<"Angle Gamma: "<<grad(a^b)<<"rad "<<f<<"\n";
return EXIT_SUCCESS;
}
You are not comparing the right angles, try this instead (create the vectors from the points you have):
double d = (a-c)^(a-b);
double e = (b-a)^(b-c);
double f = (c-b)^(c-a);
auto grad = [](double rad) { return rad * (45./atan(1.0)); };
cout<<"Angle Alpha: "<<grad((a-c)^(a-b))<<"rad "<<d;
cout<<"\nAngle Beta: "<<grad((b-a)^(b-c))<<"rad "<<e;
cout<<"\nAngle Gamma: "<<grad((c-a)^(c-b))<<"rad "<<f;
And now you have 180° or pi.

Making your classes work with floats as well as with integers (analyzing a piece of code) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm analyzing a piece of code and I came across this
class X
{
//content
};
typedef X<float> X;
Can someone points me to something closer to the source of what this (using
<type> to basically make a second class working with second type) is called, how does it work or in what cases we use this so I can continue the search. (In my case it was used as a class defining a 3-dimensional vector.)
this is the entire code:
template<typename T>
class Vec3
{
public:
T x, y, z;
Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
Vec3(T xx) : x(xx), y(xx), z(xx) {}
Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
Vec3& normalize()
{
T nor2 = length2();
if (nor2 > 0) {
T invNor = 1 / sqrt(nor2);
x *= invNor, y *= invNor, z *= invNor;
}
return *this;
}
Vec3<T> operator * (const T &f) const { return Vec3<T>(x * f, y * f, z * f); }
Vec3<T> operator * (const Vec3<T> &v) const { return Vec3<T>(x * v.x, y * v.y, z * v.z); }
T dot(const Vec3<T> &v) const { return x * v.x + y * v.y + z * v.z; }
Vec3<T> operator - (const Vec3<T> &v) const { return Vec3<T>(x - v.x, y - v.y, z - v.z); }
Vec3<T> operator + (const Vec3<T> &v) const { return Vec3<T>(x + v.x, y + v.y, z + v.z); }
Vec3<T>& operator += (const Vec3<T> &v) { x += v.x, y += v.y, z += v.z; return *this; }
Vec3<T>& operator *= (const Vec3<T> &v) { x *= v.x, y *= v.y, z *= v.z; return *this; }
Vec3<T> operator - () const { return Vec3<T>(-x, -y, -z); }
T length2() const { return x * x + y * y + z * z; }
T length() const { return sqrt(length2()); }
friend std::ostream & operator << (std::ostream &os, const Vec3<T> &v)
{
os << "[" << v.x << " " << v.y << " " << v.z << "]";
return os;
}
};
typedef Vec3<float> Vec3f;
You have probably missed some related piece of code appearing before class X:
template <typename T> // <<<<<<<<<<<<<<<<<<<<<<
class X
{
//content
};
Can someone points me to something closer to the source of what this is called,
That's called a class template.
how does it work
The code provided in the class template definition will be instantiated for various types as provided by
typedef X<float> X;
or
typedef X<int> Y;

Unresolved external symbol linker error for a function not even declared?

normally when i get this error, I go looking for a function i forgot to define, but i'm getting this from the assignment operator of a class, and i never declared it. The error goes like this:
1>SYNC_D3D11Model_Defs.obj : error LNK2019: unresolved external symbol "public: struct SYNC::Vector2 & __thiscall SYNC::Vector2::operator=(struct SYNC::Vector2 const &)" (??4Vector2#SYNC##QAEAAU01#ABU01##Z) referenced in function "public: struct VERTEX_TYPE & __thiscall VERTEX_TYPE::operator=(struct VERTEX_TYPE const &)" (??4VERTEX_TYPE##QAEAAU0#ABU0##Z)
1>SYNC_D3D11Model_Defs.obj : error LNK2019: unresolved external symbol "public: struct SYNC::Vector4 & __thiscall SYNC::Vector4::operator=(struct SYNC::Vector4 const &)" (??4Vector4#SYNC##QAEAAU01#ABU01##Z) referenced in function "public: struct VERTEX_TYPE & __thiscall VERTEX_TYPE::operator=(struct VERTEX_TYPE const &)" (??4VERTEX_TYPE##QAEAAU0#ABU0##Z)
which essentially boils down to, VERTEX_TYPE::operator= is trying to use SYNC::Vector2::operator=(const SYNC::Vector2 &) and SYNC::Vector4::operator=(SYNC::Vector2 &) but cannot find the defintions. The problem with this is, 1) I never declared, defined, or used the assignment operator in VERTEX_TYPE, 2) even if i had, those functions are indeed defined within the .cpp. Here see for yourself. These are the two offending structs and their definitions.
SYNC_Vectors.h
#ifndef SYNC_VECTORS_H
#define SYNC_VECTORS_H
#include <cmath>
namespace SYNC
{
struct Vector2
{
Vector2();
Vector2(const Vector2 & vec);
Vector2(const float & x, const float & y);
~Vector2();
inline Vector2 & operator=(const Vector2 & rhs);
inline Vector2 operator+(Vector2 rhs);
inline Vector2 operator-(Vector2 rhs);
inline Vector2 operator*(const float & scalar);
friend inline Vector2 operator*(const float & scalar, Vector2 rhs);
inline Vector2 & operator+=(const Vector2 & rhs);
inline Vector2 & operator-=(const Vector2 & rhs);
inline Vector2 & operator*=(const float & scalar);
bool operator==(const Vector2 & rhs);
bool operator!=(const Vector2 & rhs);
inline Vector2 & operator++();
inline Vector2 & operator--();
inline void Normal(Vector2 & rhs);
Vector2 & Normalize();
void Normalize(Vector2 & rhs);
Vector2 & Dot(const Vector2 & rhs1, const Vector2 & rhs2);
static float Cross(const Vector2 & lhs, Vector2 & rhs);
float x;
float y;
};
struct Vector3
{
Vector3();
Vector3(const Vector3 & vec);
Vector3(const float & x, const float & y, const float & z);
virtual ~Vector3();
inline Vector3 & operator=(const Vector3 & rhs);
inline Vector3 operator+(Vector3 rhs);
inline Vector3 operator-(Vector3 rhs);
inline Vector3 operator*(const float & scalar);
friend inline Vector3 operator*(const float & scalar, Vector3 rhs);
inline Vector3 & operator+=(const Vector3 & rhs);
inline Vector3 & operator-=(const Vector3 & rhs);
inline Vector3 & operator*=(const float & rhs);
inline bool operator==(const Vector3 & rhs);
inline bool operator!=(const Vector3 & rhs);
inline Vector3 & operator++();
inline Vector3 & operator--();
void Normalize();
void Normalize(Vector3 rhs);
void Dot(const Vector3 & vec1, const Vector3 & vec2);
void Cross(const Vector3 & vec1, const Vector3 & vec2);
float x;
float y;
float z;
};
struct Vector4
{
Vector4();
Vector4(const Vector4 & rhs);
Vector4(const float & x, const float & y, const float & z, const float & w);
~Vector4();
inline Vector4 & operator=(const Vector4 & rhs);
inline Vector4 operator+(Vector4 rhs);
inline Vector4 operator-(Vector4 rhs);
inline Vector4 operator*(const float & scalar);
friend inline Vector4 operator*(const float & scalar, Vector4 rhs);
inline Vector4 & operator+=(const Vector4 & rhs);
inline Vector4 & operator-=(const Vector4 & rhs);
inline Vector4 & operator*=(const float & rhs);
inline bool operator==(const Vector4 & rhs);
inline bool operator!=(const Vector4 & rhs);
inline Vector4 & operator++();
inline Vector4 & operator--();
float x;
float y;
float z;
float w;
};
struct Quaternion
{
Quaternion();
Quaternion(const Quaternion & rhs);
Quaternion(const Vector3 & v, const float & w);
~Quaternion();
inline Quaternion & operator=(const Quaternion & rhs);
inline bool operator==(const Quaternion & rhs);
inline bool operator!=(const Quaternion & rhs);
inline Quaternion operator*(Quaternion rhs);
inline Quaternion & mul(const Quaternion & rhs);
inline void Conjugate();
inline void Conjugate(Quaternion &);
inline void Normalize();
inline void Normalize(Quaternion &);
Vector3 v;
float w;
};
}
#endif
SYNC_Vectors.cpp
#include "SYNC_Vectors.h"
//-----------------------------------------
// SYNC::Vector2 defintions
//-----------------------------------------
SYNC::Vector2::Vector2()
{
x = 0;
y = 0;
}
SYNC::Vector2::Vector2(const Vector2 & vec)
{
x = vec.x;
y = vec.y;
}
SYNC::Vector2::Vector2(const float & ix, const float & iy)
{
x = ix;
y = iy;
}
SYNC::Vector2::~Vector2()
{
}
SYNC::Vector2 & SYNC::Vector2::operator=(const SYNC::Vector2 & rhs)
{
x = rhs.x;
y = rhs.y;
return *this;
}
SYNC::Vector2 SYNC::Vector2::operator+(SYNC::Vector2 rhs)
{
rhs.x += x;
rhs.y += y;
return rhs;
}
SYNC::Vector2 SYNC::Vector2::operator-(SYNC::Vector2 rhs)
{
rhs.x -= x;
rhs.y -= y;
return rhs;
}
SYNC::Vector2 SYNC::Vector2::operator*(const float & scalar)
{
SYNC::Vector2 ret( x * scalar, y * scalar);
return ret;
}
SYNC::Vector2 operator*(const float & scalar, SYNC::Vector2 rhs)
{
rhs.x *= scalar;
rhs.y *= scalar;
return rhs;
}
SYNC::Vector2 & SYNC::Vector2::operator+=(const Vector2 & rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
SYNC::Vector2 & SYNC::Vector2::operator-=(const Vector2 & rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
SYNC::Vector2 & SYNC::Vector2::operator*=(const float & scalar)
{
x *= scalar;
y *= scalar;
return *this;
}
bool SYNC::Vector2::operator==(const Vector2 & rhs)
{
if(rhs.x == x && rhs.y == y)
return true;
else
return false;
}
bool SYNC::Vector2::operator!=(const Vector2 & rhs)
{
if(rhs.x != x || rhs.y != y)
return true;
else
return false;
}
SYNC::Vector2 & SYNC::Vector2::operator++()
{
x++;
y++;
return *this;
}
SYNC::Vector2 & SYNC::Vector2::operator--()
{
x--;
y--;
return *this;
}
void SYNC::Vector2::Normal(Vector2 & rhs)
{
rhs.x = y;
rhs.y = -x;
}
SYNC::Vector2 & SYNC::Vector2::Normalize()
{
if(x > 0.000001 || y > 0.000001)
{
float length = sqrt((x * x) + (y * y));
x /= length;
y /= length;
}
else
{
x = 0;
y = 0;
}
return *this;
}
void SYNC::Vector2::Normalize(Vector2 & rhs)
{
if(x > 0.000001 || y > 0.000001)
{
float length = sqrt((x * x) + (y * y));
rhs.x = x / length;
rhs.y = y / length;
}
else
{
rhs.x = 0;
rhs.y = 0;
}
}
SYNC::Vector2 & SYNC::Vector2::Dot(const Vector2 & rhs1, const Vector2 & rhs2)
{
x = rhs1.x * rhs2.x;
y = rhs1.y * rhs2.y;
return *this;
}
float SYNC::Vector2::Cross(const Vector2 & rhs1, Vector2 & rhs2)
{
return ((rhs1.x * rhs2.y) - (rhs1.y * rhs2.x));
}
//-----------------------------------------
// SYNC::Vector3 defintions
//-----------------------------------------
SYNC::Vector3::Vector3()
{
x = 0;
y = 0;
z = 0;
}
SYNC::Vector3::Vector3(const Vector3 & vec)
{
x = vec.x;
y = vec.y;
z = vec.z;
}
SYNC::Vector3::Vector3(const float & ix, const float & iy, const float & iz)
{
x = ix;
y = iy;
z = iz;
}
SYNC::Vector3::~Vector3()
{
}
SYNC::Vector3 & SYNC::Vector3::operator=(const Vector3 & rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
return *this;
}
SYNC::Vector3 SYNC::Vector3::operator+(Vector3 rhs)
{
rhs.x += x;
rhs.y += y;
rhs.z += z;
return rhs;
}
SYNC::Vector3 SYNC::Vector3::operator-(Vector3 rhs)
{
rhs.x -= x;
rhs.y -= y;
rhs.z -= z;
return rhs;
}
SYNC::Vector3 SYNC::Vector3::operator*(const float & rhs)
{
Vector3 ret(x * rhs, y * rhs, z * rhs);
return ret;
}
SYNC::Vector3 operator*(const float & scalar, SYNC::Vector3 rhs)
{
rhs.x *= scalar;
rhs.y *= scalar;
rhs.z *= scalar;
return rhs;
}
SYNC::Vector3 & SYNC::Vector3::operator+=(const Vector3 & rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
SYNC::Vector3 & SYNC::Vector3::operator-=(const Vector3 & rhs)
{
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
SYNC::Vector3 & SYNC::Vector3::operator*=(const float & rhs)
{
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
bool SYNC::Vector3::operator==(const Vector3 & rhs)
{
if(x == rhs.x && y == rhs.y && z == rhs.z)
return true;
else
return false;
}
bool SYNC::Vector3::operator!=(const Vector3 & rhs)
{
if(x != rhs.x || y != rhs.y || z != rhs.z)
return true;
else
return false;
}
SYNC::Vector3 & SYNC::Vector3::operator++()
{
x++;
y++;
z++;
return *this;
}
SYNC::Vector3 & SYNC::Vector3::operator--()
{
x--;
y--;
z--;
return *this;
}
void SYNC::Vector3::Normalize()
{
if(x > 0.000001 || y > 0.000001 || z > 0.000001)
{
float length = sqrt((x * x) + (y * y) + (z * z));
x /= length;
y /= length;
z /= length;
}
else
{
x = 0;
y = 0;
z = 0;
}
}
void SYNC::Vector3::Normalize(Vector3 rhs)
{
if(x > 0.000001 || y > 0.000001 || z > 0.000001)
{
float length = sqrt((x * x) + (y * y) + (z * z));
rhs.x /= length;
rhs.y /= length;
rhs.z /= length;
}
else
{
rhs.x = 0;
rhs.y = 0;
rhs.z = 0;
}
}
void SYNC::Vector3::Dot(const Vector3 & vec1, const Vector3 & vec2)
{
x = vec1.x * vec2.x;
y = vec1.y * vec2.y;
z = vec1.z * vec2.z;
}
void SYNC::Vector3::Cross(const Vector3 & vec1, const Vector3 & vec2)
{
x = ((vec1.y * vec2.z) - (vec1.z * vec2.y));
y = ((vec1.z * vec2.x) - (vec1.x * vec2.z));
z = ((vec1.x * vec2.y) - (vec1.y * vec2.x));
}
//-----------------------------------------
// SYNC::Vector4 defintions
//-----------------------------------------
SYNC::Vector4::Vector4()
{
x = 0;
y = 0;
z = 0;
w = 0;
}
SYNC::Vector4::Vector4(const Vector4 & rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
}
SYNC::Vector4::Vector4(const float & ix, const float & iy, const float & iz, const float & iw)
{
x = ix;
y = iy;
z = iz;
w = iw;
}
SYNC::Vector4::~Vector4()
{
}
SYNC::Vector4 & SYNC::Vector4::operator=(const Vector4 & rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
return *this;
}
SYNC::Vector4 SYNC::Vector4::operator+(Vector4 rhs)
{
rhs.x += x;
rhs.y += y;
rhs.z += z;
rhs.w += w;
return rhs;
}
SYNC::Vector4 SYNC::Vector4::operator-(Vector4 rhs)
{
rhs.x += x;
rhs.y += y;
rhs.z += z;
rhs.w += w;
return rhs;
}
SYNC::Vector4 SYNC::Vector4::operator*(const float & rhs)
{
Vector4 ret( x * rhs, y * rhs, z * rhs, w * rhs);
return ret;
}
SYNC::Vector4 operator*(const float & scalar, SYNC::Vector4 rhs)
{
rhs.x *= scalar;
rhs.y *= scalar;
rhs.z *= scalar;
rhs.w *= scalar;
return rhs;
}
SYNC::Vector4 & SYNC::Vector4::operator+=(const Vector4 & rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
w += rhs.w;
return *this;
}
SYNC::Vector4 & SYNC::Vector4::operator-=(const Vector4 & rhs)
{
x += rhs.x;
y += rhs.y;
z += rhs.z;
w += rhs.w;
return *this;
}
SYNC::Vector4 & SYNC::Vector4::operator*=(const float & rhs)
{
x *= rhs;
y *= rhs;
z *= rhs;
w *= rhs;
}
bool SYNC::Vector4::operator==(const Vector4 & rhs)
{
if(x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w)
return true;
else
return false;
}
bool SYNC::Vector4::operator!=(const Vector4 & rhs)
{
if(x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w)
return true;
else
return false;
}
SYNC::Vector4 & SYNC::Vector4::operator++()
{
x++;
y++;
z++;
w++;
}
SYNC::Vector4 & SYNC::Vector4::operator--()
{
x--;
y--;
z--;
w--;
}
//---------------------------------
// SYNC::Quaternion definitions
//---------------------------------
SYNC::Quaternion::Quaternion()
{
v.x = 0;
v.y = 0;
v.z = 0;
w = 0;
}
SYNC::Quaternion::Quaternion(const Quaternion & rhs)
{
v.x = rhs.v.x;
v.y = rhs.v.y;
v.z = rhs.v.z;
w = rhs.w;
}
SYNC::Quaternion::Quaternion(const Vector3 & iv, const float & iw)
{
v = iv;
w = iw;
}
SYNC::Quaternion::~Quaternion()
{
}
SYNC::Quaternion & SYNC::Quaternion::operator=(const Quaternion & rhs)
{
v = rhs.v;
w = rhs.w;
}
bool SYNC::Quaternion::operator==(const Quaternion & rhs)
{
if(v == rhs.v && w == rhs.w)
return true;
else
return false;
}
bool SYNC::Quaternion::operator!=(const Quaternion & rhs)
{
if(v != rhs.v || w != rhs.w)
return true;
else
return false;
}
SYNC::Quaternion SYNC::Quaternion::operator*(Quaternion rhs)
{
rhs.v.x = (w * rhs.v.x) + (v.x * rhs.w) + (v.y * rhs.v.z) - (v.z * rhs.v.y);
rhs.v.y = (w * rhs.v.y) - (v.x * rhs.v.z) + (v.y * rhs.w) + (v.z * rhs.v.x);
rhs.v.z = (w * rhs.v.z) + (v.x * rhs.v.y) - (v.y * rhs.v.x) + (v.z * rhs.w);
rhs.w = (w * rhs.w) - (v.x * rhs.v.x) - (v.y * rhs.v.y) - (v.z * rhs.v.z);
return rhs;
}
SYNC::Quaternion & SYNC::Quaternion::mul(const Quaternion & rhs)
{
v.x = (w * rhs.v.x) + (v.x * rhs.w) + (v.y * rhs.v.z) - (v.z * rhs.v.y);
v.y = (w * rhs.v.y) - (v.x * rhs.v.z) + (v.y * rhs.w) + (v.z * rhs.v.x);
v.z = (w * rhs.v.z) + (v.x * rhs.v.y) - (v.y * rhs.v.x) + (v.z * rhs.w);
w = (w * rhs.w) - (v.x * rhs.v.x) - (v.y * rhs.v.y) - (v.z * rhs.v.z);
return *this;
}
void SYNC::Quaternion::Conjugate()
{
v *= -1;
}
void SYNC::Quaternion::Conjugate(Quaternion & rhs)
{
rhs.v = v * -1;
rhs.w = w;
}
void SYNC::Quaternion::Normalize()
{
float length = sqrt((w*w) + (v.x * v.x) + (v.y * v.y) + (v.z * v.z));
if(length > 0.000001)
{
v.x /= length;
v.y /= length;
v.z /= length;
w /= length;
}
else
{
v.x = 0;
v.y = 0;
v.z = 0;
w = 0;
}
}
void SYNC::Quaternion::Normalize(Quaternion & rhs)
{
float length = sqrt((w*w) + (v.x * v.x) + (v.y * v.y) + (v.z * v.z));
if(length > 0.000001)
{
rhs.v.x = v.x / length;
rhs.v.y = v.y / length;
rhs.v.z = v.z / length;
rhs.w = w / length;
}
else
{
rhs.v.x = 0;
rhs.v.y = 0;
rhs.v.z = 0;
rhs.w = 0;
}
}
syncmod.h
#ifndef SYNCMOD_H
#define SYNCMOD_H
#include <fstream>
#include <map>
#include <string>
#include "SYNC_Vectors.h"
struct SYNCMODEL_HEADER
{
char id[8];
short ver[2];
long m_numOfVertices;
long m_numOfIndices;
std::string m_modelName;
};
struct VERTEX_TYPE
{
SYNC::Vector3 position;
SYNC::Vector4 color;
SYNC::Vector3 normal;
SYNC::Vector3 binormal;
SYNC::Vector3 tangent;
SYNC::Vector2 textureCoords;
};
class SYNCMODEL_MATERIAL_HEADER
{
enum DATA_TYPE{MATERIAL_SHORT , MATERIAL_INT, MATERIAL_LONG, MATERIAL_FLOAT, MATERIAL_DOUBLE};
struct Data_Index
{
DATA_TYPE type;
char * accessor;
};
int m_numOfElements;
std::map<std::string, Data_Index> m_Indices;
};
std::ifstream & operator>>(std::ifstream & stream, SYNCMODEL_HEADER & header);
#endif
syncmod.cpp
#include "syncmod.h"
std::ifstream & operator>>(std::ifstream & stream, SYNCMODEL_HEADER & header)
{
stream.read(header.id, 8);
stream.read(reinterpret_cast<char *>(&header.ver), sizeof(short) * 2);
stream.read(reinterpret_cast<char *>(&header.m_numOfVertices), sizeof(long));
stream.read(reinterpret_cast<char *>(&header.m_numOfIndices), sizeof(long));
std::getline(stream, header.m_modelName, '\0');
stream.seekg(static_cast<int>(stream.tellg()) - 1);
return stream;
}
anyone know what the heck is going on here?
edit: Just an additional observation here, why is it throwing up flags with just the assignment operator of these two and not SYNC::Vector3?
The header SYNC_Vectors.h declares:
inline Vector2 & operator=(const Vector2 & rhs);
and the source file SYNC_Vectors.cpp defines:
SYNC::Vector2 & SYNC::Vector2::operator=(const SYNC::Vector2 & rhs)
Remove the inline from the declaration and things should get better. <g> Or, as we've discussed, put the definitions of the inline functions into SYNC_Vectors.h, either by copying the text or with a #include directive at the end of the file. For the latter, most people use a distinctive extension, often .inl.