Connecting the C++ class with the LUA table - c++

I am trying to connect my 3d engine to a lua (5.1) parser.
For example, I have a LUA class of a vec3 and I have a C++ class of a vec3. I want them to work with eachother.
This is (part) of my C++ class:
class vec3
{
public:
vec3() {}
vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
vec3 operator+(const vec3 &b)
{
return vec3(x + b.x, y + b.y, z + b.z);
}
float dot(const vec3 &b)
{
return x * b.x + y * b.y + z * b.z;
}
float x, y, z;
}
This is the (limited) lua version:
vec3 = {};
vec3.__index = vec3;
local mt = {}
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj, vec3);
vec3.init(obj, ...);
return obj;
end
vec3.init = function(obj, x, y, z)
obj.x, obj.y, obj.z = x, y, z;
end
setmetatable(vec3, mt);
function vec3:__tostring()
return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")";
end
function vec3:__add(b)
return vec3(self.x + b.x, self.y + b.y, self.z + b.z);
end
function vec3:dot(b)
return self.x * b.x + self.y * b.y + self.z * b.z;
end
I think the question is quite obvious: I want to be able to use vec3's in my C++ code, for example to position nodes or other stuff and then I want to be able to make these available in LUA where the LUA-programmer can do math with the vec3's and send them back to C++. So I also want to be able to construct a vec3 in LUA and send it to C++ where it is understood as a vec3 class.
To achieve this, I think I need to construct the above LUA table in C instead of in LUA and I need to create a function "push" and "pop" to send them to LUA and retrieve them from LUA.
But all my trials fail.
Can anyone help me get this to work?
Dirk.

What you need to do is create a userdata on the Lua stack in C++ and use that as the object. You can fairly simply placement new into it and arrange the metatable from C++. Of course, this is hideously type-unsafe, amongst the other huge holes in the Lua system.

Why not try to use C++ packages like luabind or luabridge? In those you you can access any lua data from C++ and vice versa.

Related

Using neon/simd to optimize Vector3 class

I'd like to know if it is worth it optimizing my Vector3 class' operations with neon/simd like I did to my Vector2 class.
As far as I know, simd can only handle two or four floats at the same time, so to my Vector3 we would need something like this:
Vector3 Vector3::operator * (const Vector3& v) const
{
#if defined(__ARM_NEON__)
// extra step: allocate a fourth float
const float v4A[4] = {x, y, z, 0};
const float v4B[4] = {v.x, v.y, v.z, 0};
float32x4_t r = vmul_f32(*(float32x4_t*)v4A, *(float32x4_t*)v4B);
return *(Vector3*)&r;
#else
return Vector3(x * v.x, y * v.y, z * v.z);
#endif
}
Is this safe? Would this extra step still be faster than a non-simd code on most scenarios (say arm64 for instance)?

Check if mouse is within triangle C++

I'm making a application for school in which I have to click a particular object.
EDIT: This is being made in 2D
I have a rectangle, I rotate this rectangle by X.
The rotation of the rectangle has made my rectangles (x,y,width,height) become a new rectangle around the rotated rectangle.
http://i.stack.imgur.com/MejMA.png
(excuse me for my terrible paint skills)
The Black lines describe the rotated rectangle, the red lines are my new rectangle.
I need to find out if my mouse is within the black rectangle or not. Whatever rotation I do I already have a function for getting the (X,Y) for each corner of the black rectangle.
Now I'm trying to implement this Check if point is within triangle (The same side technique).
So I can either check if my mouse is within each triangle or if theres a way to check if my mouse is in the rotated rectangle that would be even better.
I practically understand everything written in the triangle document, but I simply don't have the math skills to calculate the cross product and the dot product of the 2 cross products.
This is supposed to be the cross product:
a × b = |a| |b| sin(θ) n
|a| is the magnitude (length) of vector a
|b| is the magnitude (length) of vector b
θ is the angle between a and b
n is the unit vector at right angles to both a and b
But how do I calculate the unit vector to both a and b?
And how do I get the magnitude of a vector?
EDIT:
I forgot to ask for the calculation of the dotproduct between 2 cross products.
function SameSide(p1,p2, a,b)
cp1 = CrossProduct(b-a, p1-a)
cp2 = CrossProduct(b-a, p2-a)
if DotProduct(cp1, cp2) >= 0 then return true
else return false
Thank you everyone for your help I think I got the hang of it now, I wish I could accept multiple answers.
If you are having to carry out loads of check, I would shy away from using square root functions: they are computationally expensive. for comparison purposes, just multiply everything by itself and you can bypass the square rooting:
magnitude of vector = length of vector
If vector is defined as float[3] length can be calculated as follows:
double magnitude = sqrt( a[0]*a[0] + a[1]*a[1] + a[2]*a[2] );
However that is expensive computationally so I would use
double magnitudeSquared = a[0]*a[0] + a[1]*a[1] + a[2]*a[2];
Then modify any comparative calculations to use the squared version of the distance or magnitude and it will be more performant.
For the cross product, please forgive me if this maths is shaky, it has been a couple of years since I wrote functions for this (code re-use is great but terrible for remembering things):
double c[3];
c[0] = ( a[1]*b[2] - a[2]*b[1] );
c[1] = ( a[2]*b[0] - a[0]*b[2] );
c[2] = ( a[0]*b[1] - a[1]*b[0] );
To simplify it all I would put a vec3d in a class of its own, with a very simple representation being:
class vec3d
{
public:
float x, y, z;
vec3d crossProduct(vec3d secondVector)
{
vec3d retval;
retval.x = (this.y * secondVector.z)-(secondVector.y * this.z);
retval.y = -(this.x * secondVector.z)+(secondVector.x * this.z);
retval.z = (this.x * secondVector.y)-(this.y * secondVector.x);
return retval;
}
// to get the unit vector divide by a vectors length...
void normalise() // this will make the vector into a 1 unit long variant of itself, or a unit vector
{
if(fabs(x) > 0.0001){
x= x / this.magnitude();
}
if(fabs(y) > 0.0001){
y= y / this.magnitude();
}
if(fabs(z) > 0.0001){
z = / this.magnitude();
}
}
double magnitude()
{
return sqrt((x*x) + (y*y) + (z*z));
}
double magnitudeSquared()
{
return ((x*x) + (y*y) + (z*z));
}
};
A fuller implementation of a vec3d class can be had from one of my old 2nd year coding excercises: .h file and .cpp file.
And here is a minimalist 2d implementation (doing this off the top of my head so forgive the terse code please, and let me know if there are errors):
vec2d.h
#ifndef VEC2D_H
#define VEC2D_H
#include <iostream>
using namespace std;
class Vec2D {
private:
double x, y;
public:
Vec2D(); // default, takes no args
Vec2D(double, double); // user can specify init values
void setX(double);
void setY(double);
double getX() const;
double getY() const;
double getMagnitude() const;
double getMagnitudeSquared() const;
double getMagnitude2() const;
Vec2D normalize() const;
double crossProduct(Vec2D secondVector);
Vec2D crossProduct(Vec2D secondVector);
friend Vec2D operator+(const Vec2D&, const Vec2D&);
friend ostream &operator<<(ostream&, const Vec2D&);
};
double dotProduct(const Vec2D, const Vec2D);
#endif
vec2d.cpp
#include <iostream>
#include <cmath>
using namespace std;
#include "Vec2D.h"
// Constructors
Vec2D::Vec2D() { x = y = 0.0; }
Vec2D::Vec2D(double a, double b) { x = a; y = b; }
// Mutators
void Vec2D::setX(double a) { x = a; }
void Vec2D::setY(double a) { y = a; }
// Accessors
double Vec2D::getX() const { return x; }
double Vec2D::getY() const { return y; }
double Vec2D::getMagnitude() const { return sqrt((x*x) + (y*y)); }
double Vec2D::getMagnitudeSquared() const { return ((x*x) + (y*y)); }
double Vec2D::getMagnitude2 const { return getMagnitudeSquared(); }
double Vec2d::crossProduct(Vec2D secondVector) { return ((this.x * secondVector.getY())-(this.y * secondVector.getX()));}
Vec2D crossProduct(Vec2D secondVector) {return new Vec2D(this.y,-(this.x));}
Vec2D Vec2D::normalize() const { return Vec2D(x/getMagnitude(), y/getMagnitude());}
Vec2D operator+(const Vec2D& a, const Vec2D& b) { return Vec2D(a.x + b.x, a.y + b.y);}
ostream& operator<<(ostream& output, const Vec2D& a) { output << "(" << a.x << ", " << a.y << ")" << endl; return output;}
double dotProduct(const Vec2D a, const Vec2D b) { return a.getX() * b.getX() + a.getY() * b.getY();}
Check if a point is inside a triangle described by three vectors:
float calculateSign(Vec2D v1, Vec2D v2, Vec2D v3)
{
return (v1.getX() - v3.getX()) * (v2.getY() - v3.getY()) - (v2.getX() - v3.getX()) * (v1.getY() - v3.getY());
}
bool isPointInsideTriangle(Vec2D point2d, Vec2D v1, Vec2D v2, Vec2D v3)
{
bool b1, b2, b3;
// the < 0.0f is arbitrary, could have just as easily been > (would have flipped the results but would compare the same)
b1 = calculateSign(point2d, v1, v2) < 0.0f;
b2 = calculateSign(point2d, v2, v3) < 0.0f;
b3 = calculateSign(point2d, v3, v1) < 0.0f;
return ((b1 == b2) && (b2 == b3));
}
In the code above if calculateSign is in the triangle you will get a true returned :)
Hope this helps, let me know if you need more info or a fuller vec3d or 2d class and I can post:)
Addendum
I have added in a small 2d-vector class, to show the differences in the 2d and 3d ones.
The magnitude of a vector is its length. In C++, if you have a vector represented as a double[3], you would calculate the length via
#include <math.h>
double a_length = sqrt( a[0]*a[0] + a[1]*a[1] + a[2]*a[2] );
However, I understand what you actually want is the cross product? In that case, you may want to calculate it directly. The result is a vector, i.e. c = a x b.
You code it like this for example:
double c[3];
c[0] = ( a[2]*b[3] - a[3]*b[2] );
c[1] = ( a[3]*b[1] - a[1]*b[3] );
c[2] = ( a[1]*b[2] - a[2]*b[1] );
You can calculate the magnitude of vector by sqrt(x*x + y*y). Also you can calculate the crossproduct simpler: a x b = a.x * b.y - a.y * b.x. Checking that a point is inside triangle can be done by counting the areas for all 4 triangles. For example a is the area of the source triangle, b,c,d are areas of other ones. If b + c + d = a then the point is inside. Counting the area of triangle is simple: we have vectors a, b that are vertexes of triangle. The area of triangle then is (a x b) / 2
One simple way without getting into vectors is to check for area.
For example ,lets say you have a rectangle with corners A,B,C,D. and point P.
first calculate the area of rectangle, simply find height and width of the rectangle and multiply.
B D
| /
| /
|/____ C
A
For calculating the height,width take one point lets say A, find its distance from all other three points i.e AB,AC,AD 1st and 2nd minimum will be width,and height, max will be diagonal length.
Now store the points from which you get the height, width, lets says those points are B,C.
So now you know how rectangle looks, i.e
B _____ D
| |
|_____|
A C
Then calculate the sum of area of triangles ACP,ABP,BDP,CDP (use heros formula to compute area of rectangle), if it equals to the area of rectangle, point P is inside else outside the rectangle.

no default constructor exists

I'm having some trouble with a class that was working fine and now doesn't seem to want to work at all.
The error is "No appropriate default constructor available"
I am using the class in two places I'm making a list of them and initializing then adding them to the list.
Vertice3f.h
#pragma once
#include "Vector3f.h"
// Vertice3f hold 3 floats for an xyz position and 3 Vector3f's
// (which each contain 3 floats) for uv, normal and color
class Vertice3f{
private:
float x,y,z;
Vector3f uv, normal, color;
public:
// If you don't want to use a UV, Normal or Color
// just pass in a Verctor3f with 0,0,0 values
Vertice3f(float _x, float _y, float _z, Vector3f _uv,
Vector3f _normal, Vector3f _color);
~Vertice3f();
};
Vertice3f.cpp
#include "Vertice3f.h"
Vertice3f::Vertice3f(float _x, float _y, float _z,
Vector3f _uv, Vector3f _normal, Vector3f _color){
x = _x;
y = _y;
z = _z;
uv = _uv;
normal = _normal;
color = _color;
}
It is being using in my OBJModelLoader class as follows:
list<Vertice3f> vert3fList;
Vertice3f tvert = Vertice3f(
x = (float)atof(
vertList[i].substr(
vertList[i].find("v") + 1,
vertList[i].find(" ", vertList[i].find("v") + 2, 10)
).c_str()
),
y = (float)atof(
vertList[i].substr(
vertList[i].find(" ", vertList[i].find("v") + 4, 10) + 1,
vertList[i].find(" ", vertList[i].find("v") + 13, 10)
).c_str()
),
z = (float)atof(
vertList[i].substr(
vertList[i].find(" ", vertList[i].find("v") + 13, 10) + 1,
vertList[i].find(" ", vertList[i].find("v") + 23, 10)
).c_str()
),
::Vector3f(0.0f,0.0f,0.0f),::Vector3f(0.0f,0.0f,0.0f),::Vector3f(0.0f,0.0f,0.0f)
);
vert3fList.push_back(
tvert
);
I have tried defining a default constructor myself so in the .h I put
Vertice3f();
and in the cpp
Vertice3f::Vertice3f(){
x = 0.0f;
y = 0.0f;
z = 0.0f;
uv = Vector3f(0.0f,0.0f,0.0f);
normal = Vector3f(0.0f,0.0f,0.0f);
color = Vector3f(0.0f,0.0f,0.0f);
}
So, I'm not sure why it can't find a default constructor or how to appease the compiler. I'm sure it's user error because the compiler probably knows what it's doing.
Any help is greatly appreciated, I will answer any other questions you have, just ask.
I'd guess that the missing default constructor is the default constructor of Vector3f class, not of Vertice3f class. Your constructor of Vertice3f attempts to default-construct its Vector3f members, which leads to the error.
This is why your attempts to provide default constructor for Vertice3f don't change anything. The problem lies, again, with Vector3f.
To fix it either provide all necessary default constructors (assuming it agrees with your design), or rewrite the constructor of Vertice3f by using initializer list instead of in-body assignment
Vertice3f::Vertice3f(float _x, float _y, float _z,
Vector3f _uv, Vector3f _normal, Vector3f _color) :
x(_x), y(_y), z(_z), uv(_uv), normal(_normal), color(_color)
{}
This version no longer attempts to default-construct anything. And using initializer list instead of in-body assignment is a good idea in any case.

C++ data structures: converting from TNT Vector to GL vec3

I'm using a data structure not written by myself that returns a realVec. This is the declaration of realVec (in typedef.h):
typedef TNT::Vector<PCReal> realVec;
For the definition of TNT Vector please see: http://calicam.sourceforge.net/doxygen/tnt__vector_8h_source.html
Definition of PCReal:
typedef double PCReal;
I need to convert this realVec into the following vec3:
struct vec3 {
GLfloat x;
GLfloat y;
GLfloat z;
//
// --- Constructors and Destructors ---
//
vec3( GLfloat s = GLfloat(0.0) ) :
x(s), y(s), z(s) {}
vec3( GLfloat _x, GLfloat _y, GLfloat _z ) :
x(_x), y(_y), z(_z) {}
vec3( const vec3& v ) { x = v.x; y = v.y; z = v.z; }
vec3( const vec2& v, const float f ) { x = v.x; y = v.y; z = f; }
...
I'm very new to C++ so my confusion probably lies in using TNT::Vector's iterator and converting values returned by it. I'm thinking something like the below, so tell me if it makes sense. It seems to compile (no 'make' errors):
realVec normal = this->meshPoints.getNormalForVertex(i);
PCReal* iter = normal.begin();
vec3(*iter++, *iter++, *iter++);
I need this because I'm doing gl programming, and it's convenient for my shaders to take vec3's as input.
What you have might work, but you could improve it with some safety checks, and you don't really have to use iterators at all. It appears realVec provides operator[] like most other vector classes.
realVec normal = this->meshPoints.getNormalForVertex(i);
if (normal.size() >= 3)
{
vec3 x(normal[0], normal[1], normal[2]);
}

Function is causing huge memory leak?

I have the following function:
void CGlEngineFunctions::GetBezierOpposite( const POINTFLOAT &a,const POINTFLOAT &center, POINTFLOAT &b, float blength )
{
POINTFLOAT v;
v.x = a.x - center.x;
v.y = a.y - center.y;
float alength = GetDistance(a,center);
if(blength == 0)
{
blength = alength;
}
float multiplier = blength / alength;
b.x = center.x - multiplier * v.x;
b.y = center.y - multiplier * v.y;
}
I have narrowed the problem down to the least 2 lines:
b.x = center.x - multiplier * v.x;
b.y = center.y - multiplier * v.y;
Every time I call this repeatedly, memory shots up until it crashes.
I use it like this:
glEngine.functions.GetBezierOpposite(usrpt[0].LeftHandle,
usrpt[0].UserPoint,usrpt[0].RightHandle,0);
I really do not see how this could cause any problems.
To test, I changed it to this:
void CGlEngineFunctions::GetBezierOpposite( const POINTFLOAT &a,const POINTFLOAT &center, POINTFLOAT &b, float blength )
{
POINTFLOAT v;
v.x = a.x - center.x;
v.y = a.y - center.y;
float alength = GetDistance(a,center);
if(blength == 0)
{
blength = alength;
}
float multiplier = blength / alength;
b.x = 5;
b.y = 5;
}
When I do this it has absolutely no issues. I do not see how doing arithmetic can cause the memory usage to shoot up.
Thanks
could it be cause if alength and blength = 0?
POINTFLOAT:
float x;
float y;
If the GetDistance calls this method, there may be a Stack Overflow.
If other threads call this method, there may be a Stack Overflow.
Check the POINTFLOAT definition. IMHO, it should be modified to provide subtraction operations. You should not need to reference any of the structure's members. But then this comment would be about C++.
You should remove the 'C' language tag, since the C language does not provide a scope resolution operator, '::'.
If POINTFLOAT is some complicated class (you have tagged your question C++) and you have overloaded the operators in the expression, how could we know?
Also you didn't tell us much why you think these expression are the culprit, neither about your compiler, platform, OS...
Easiest way to find all this out is valgrind (for unixen) or some similar tool. They will tell you exactly where the allocation takes place that ends up being leaked.