GameDev.net Posting Guidelines (please read before posting)
For Beginners Forum FAQs (please read before posting)
Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
Posted 20 June 2011 - 12:33 PM
Posted 20 June 2011 - 12:53 PM
Posted 20 June 2011 - 01:09 PM
It is legal, and normal, for people to post code. Please produce a minimal example if you are going to post code.
From your description I imagine it will be a rule of three violation. Using std::vector<> instead of new[] and delete[] will probably solve it.
#ifndef VECTORS_H_INCLUDED #define VECTORS_H_INCLUDED class Vector3f { public: Vector3f(); Vector3f(float x, float y, float z); ~Vector3f(); float getX(); float getY(); float getZ(); void setX(float x); void setY(float y); void setZ(float z); void add(Vector3f * v3f); void sub(Vector3f * v3f); void multiply(float f); void divide(float f); void crossProduct(Vector3f * v); float dot(Vector3f * v); private: float _x; float _y; float _z; void normalize(); }; #endif
#include "Vectors.h" #include <math.h> Vector3f::Vector3f(){ _x = 0; _y = 0; _z = 0; } Vector3f::Vector3f(float x, float y, float z){ _x = x; _y = y; _z = z; } Vector3f::~Vector3f(){} float Vector3f::getX(){ return _x; } float Vector3f::getY(){ return _y; } float Vector3f::getZ(){ return _z; } void Vector3f::setX(float x){ _x = x; } void Vector3f::setY(float y){ _y = y; } void Vector3f::setZ(float z){ _z = z; } void Vector3f::add(Vector3f * v3f){ _x+=v3f->getX(); _y+=v3f->getY(); _z+=v3f->getZ(); } void Vector3f::sub(Vector3f * v3f){ _x-=v3f->getX(); _y-=v3f->getY(); _z-=v3f->getZ(); } void Vector3f::multiply(float f){ _x*=f; _y*=f; _z*=f; } void Vector3f::divide(float f){ _x/=f; _y/=f; _z/=f; } void Vector3f::crossProduct(Vector3f * v){ float tempX = _y*v->getZ() - _z*v->getY(); float tempY = _z*v->getX() - _x*v->getZ(); _z = _x*v->getY() - _y*v->getX(); _x = tempX; _y = tempY; normalize(); } void Vector3f::normalize(){ float length = sqrtf( (_x*_x) + (_y*_y) + (_z*_z) ); _x/=length; _y/=length; _z/=length; } float Vector3f::dot(Vector3f * v){ return _x * v->getX() + _y * v->getY() + _z * v->getZ(); }
#ifndef TRIANGLE_H_INCLUDED #define TRIANGLE_H_INCLUDED #include "Vectors.h" #include <Windows.h> #include <GL\gl.h> #include <GL\glu.h> #include <glut.h> //represents a triangle class Triangle { public: Triangle(); Triangle(Vector3f *p0, Vector3f *p1, Vector3f *p2); ~Triangle(); Vector3f * _p0; Vector3f * _p1; Vector3f * _p2; Vector3f * _v1; Vector3f * _v2; Vector3f * _normalVec; float forDist; void draw(); }; #endif
#include "Triangle.h" #include <iostream> using namespace std; Triangle::Triangle(){ } Triangle::Triangle(Vector3f *p0, Vector3f *p1, Vector3f *p2){ _p0 = p0; _p1 = p1; _p2 = p2; _v1 = new Vector3f(p1->getX() - p0->getX(), p1->getY() - p0->getY(), p1->getZ() - p0->getZ()); _v2 = new Vector3f(p2->getX() - p0->getX(), p2->getY() - p0->getY(), p2->getZ() - p0->getZ()); _normalVec = new Vector3f(p1->getX() - p0->getX(), p1->getY() - p0->getY(), p1->getZ() - p0->getZ()); _normalVec->crossProduct(_v2); forDist = -(_normalVec->getX() * p0->getX() + _normalVec->getY() * p0->getY() + _normalVec->getZ() * p0->getZ()); } Triangle::~Triangle(){ delete _p0; delete _p1; delete _p2; delete _v1; delete _v2; delete _normalVec; } void Triangle::draw(){ //TODO - AO ALTERAR A POSICAO DO TRIANGULO E NECESSARIO FAZER UPDATE A ESTA VARIAVEL! forDist = -(_normalVec->getX() * _p0->getX() + _normalVec->getY() * _p0->getY() + _normalVec->getZ() * _p0->getZ()); cout<<_p0->getX()<<" "<< _p0->getY()<<" "<< _p0->getZ()<<endl; cout<<_p1->getX()<<" "<< _p1->getY()<<" "<< _p1->getZ()<<endl; cout<<_p2->getX()<<" "<< _p2->getY()<<" "<< _p2->getZ()<<endl<<endl; glBegin(GL_TRIANGLES); glVertex3f(_p0->getX(), _p0->getY(), _p0->getZ()); glVertex3f(_p1->getX(), _p1->getY(), _p1->getZ()); glVertex3f(_p2->getX(), _p2->getY(), _p2->getZ()); glEnd(); }
#ifndef IMAGEUTILS_H_INCLUDED #define IMAGEUTILS_H_INCLUDED #include "Triangle.h" class TriangleMesh{ public: bool color; int nOfTriangles; Vector3f *vertexes; TriangleMesh(int nTrianglesBySide, float cateteSize, float bottomLeftStartXPosfloat,float bottomLeftStartZPos); ~TriangleMesh(); void Draw(); protected: private: Triangle * triangles; void fillTrianglePointer(int nTrianglesBySide); void fillVectorPointer(int nTrianglesBySide, float cateteSize, float bottomLeftStartXPosfloat,float bottomLeftStartZPos); }; #endif
#include "TriangleMesh.h" #include <iostream> #include <GL\gl.h> using namespace std; TriangleMesh::TriangleMesh(int nTrianglesBySide, float cateteSize,float bottomLeftStartXPos,float bottomLeftStartZPos){ color = true; nOfTriangles = nTrianglesBySide*nTrianglesBySide*2; fillVectorPointer(nTrianglesBySide, cateteSize,bottomLeftStartXPos,bottomLeftStartZPos); fillTrianglePointer(nTrianglesBySide); } TriangleMesh::~TriangleMesh(){ } void TriangleMesh::Draw(){ for(int index = 0; index <nOfTriangles;index++){ if(color) glColor3f(1,0,0); else glColor3f(0,1,0); color = !color; triangles[index].draw(); } } void TriangleMesh::fillVectorPointer(int nTrianglesBySide, float cateteSize,float bottomLeftStartXPosfloat,float bottomLeftStartZPos){ int totalNumOfVertexes = (nTrianglesBySide+1)*(nTrianglesBySide+1) ; vertexes = new Vector3f[totalNumOfVertexes]; float xPos = bottomLeftStartXPosfloat; float zPos = bottomLeftStartZPos; for(int index = 0; index < totalNumOfVertexes; index++){ if(index!=0 && (index%4) == 0){ xPos = bottomLeftStartXPosfloat; zPos -=cateteSize; } vertexes[index] = Vector3f(xPos, 0, zPos); xPos += cateteSize; } } void TriangleMesh::fillTrianglePointer(int nTrianglesBySide){ int totalNumOfTriangles = (nTrianglesBySide*nTrianglesBySide*2) ; triangles = new Triangle[totalNumOfTriangles]; int auxIndex0 = 0; int auxIndex1 = 1; int auxIndex2 = nTrianglesBySide+1; int auxIndex3 = nTrianglesBySide+2; int vertexIndex0 = 0; int vertexIndex1 = 1; int vertexIndex2 = nTrianglesBySide+1; int vertexIndex3 = nTrianglesBySide+2; int numOfTrianglesPerLine = nTrianglesBySide*2; for(int index = 0; index < totalNumOfTriangles; index+=2){ if(index>numOfTrianglesPerLine){ auxIndex0 = auxIndex2; auxIndex1 = auxIndex3; auxIndex2 = auxIndex0+nTrianglesBySide+1; auxIndex3 = auxIndex2; vertexIndex0 = auxIndex0; vertexIndex1 = auxIndex1; vertexIndex2 = auxIndex2; vertexIndex3 = auxIndex3; } triangles[index] = Triangle(&vertexes[vertexIndex0],&vertexes[vertexIndex1],&vertexes[vertexIndex2]); triangles[index+1] = Triangle(&vertexes[vertexIndex1],&vertexes[vertexIndex3],&vertexes[vertexIndex2]); vertexIndex0++; vertexIndex1++; vertexIndex2++; vertexIndex3++; } } int main(){ TriangleMesh tm(3,1,0,0); cin.get(); return 0; }
Posted 20 June 2011 - 01:41 PM
void Vector3f::add(const Vector3f &v){ _x += v3f.getX(); _y += v3f.getY(); _ z+= v3f.getZ(); } void Vector3f::sub(const Vector3f &v){ _x -= v3f.getX(); _y -= v3f.getY(); _z -= v3f.getZ(); }Something like this, with the appropriate changes to the declarations in the header file.
class Triangle { public: Triangle(); Triangle(const Vector3f &p0, const Vector3f &p1, const Vector3f &p2); Vector3f _p0; Vector3f _p1; Vector3f _p2; Vector3f _v1; Vector3f _v2; Vector3f _normalVec; float forDist; void draw(); };You'll note I use const references for the constructor parameters. This just avoids making an additional copy when passing them to the function. Again we can remove the destructor as the default, compiler generated version will simply destroy all the members, which aren't pointers so everything will be correctly cleaned up.
Triangle::Triangle(const Vector3f &p0, const Vector3f &p1, const Vector3f &p2) : _p0(p0), _p1(p1), _p2(p2), { _v1 = p1; _v1.sub(p0); _v2 = p2; _v2.sub(p0); _normalVec = p1; _normalVec.sub(p0); _normalVec->crossProduct(_v2); forDist = -(_normalVec.getX() * p0.getX() + _normalVec.getY() * p0.getY() + _normalVec.getZ() * p0.getZ()); }I'm using the functions you've defined to simplify this a little. If the functions were pure it would be even easier.
#include <vector> class TriangleMesh{ public: bool color; TriangleMesh(int nTrianglesBySide, float cateteSize, float bottomLeftStartXPosfloat,float bottomLeftStartZPos); void Draw(); private: std::vector<Vertex3f> vertices; std::vector<Triangle> triangles; void fillTrianglePointer(int nTrianglesBySide); void fillVectorPointer(int nTrianglesBySide, float cateteSize, float bottomLeftStartXPosfloat,float bottomLeftStartZPos); };There are various member functions for manipulating vector<>, there is push_back(), which is analogous to ArrayList#add(). You can access elements using the array bracket syntax, e.g. vertices[42]. You can get the length using size(). There is also a nested iterator type for blazing through the array in a loop.
Posted 20 June 2011 - 02:56 PM
Posted 20 June 2011 - 03:19 PM
Good stuff!ok dude, I understand most things you have done
I don't really think of it as an optimisation. It expresses my intent: did I intend to make a copy here? If so, pass by value. I not pass by const reference. In the case of primitives I always pass by value because the distinction is blurred, and it is idiomatic in most languages to copy primitives even when no copy is strictly necessary.the "const Vector3f &v" was somehow new to me,but it's like you said, it's a little optimization in the code, optimizations are always good x)
Let us examine this line:by the way, after all that i still haven't understood the reason for my dynamic memory allocation failures, with new ... [] or malloc (tried this before the new), but anyway thanks for the reaply, will try to post something as soon as I am done with the changes
triangles[index] = Triangle(&vertexes[vertexIndex0],&vertexes[vertexIndex1],&vertexes[vertexIndex2]);What does it do? It creates a temporary triangle from the three pointers specified. This triangle is copied into the array. The temporary is implicitly destroyed, which calls ~Triangle(). The triangle destructor calls delete on the pointers (which isn't valid because the pointers weren't individually allocated by new).
No, you will not. One solution is to move to an indexed model, so you have one authoritative array of vertices and the triangles are made up of integer indices into this array. This avoids storing duplicate vertices where triangles meet.I used so many pointers because like that I can change one of the vertices and that way there is no need to change the triangle Vector3fs, with your solution will I still get that?
Posted 20 June 2011 - 03:53 PM
#pragma once #include <cmath> #include "BOOST/operators.hpp" //Boost operators used to produce arithmatic operators based on the compound assignment ones, e.g. a + b from += //To reduce object size, the templates are chained struct Vec2d // note: private inheritance is OK here! : boost::additive< Vec2d // point + point and point - point , boost::dividable2< Vec2d, double // point / T , boost::multipliable2< Vec2d, double // point * T, T * point > > > { double x,y; Vec2d(): x(0), y(0) {} Vec2d(double newx, double newy): x(newx), y(newy) {} Vec2d operator-() const {return Vec2d(-x,-y);} Vec2d& operator+= (const Vec2d& arg) { x+=arg.x; y+=arg.y; return *this; } Vec2d& operator-= (const Vec2d& arg) { x-=arg.x; y-=arg.y; return *this; } Vec2d& operator/= (double arg) { x/=arg; y/=arg; return *this; } Vec2d& operator*= (double arg) { x*=arg; y*=arg; return *this; } }; inline double operator* (const Vec2d& lhs, const Vec2d& rhs) { return (lhs.x * rhs.x) + (lhs.y * rhs.y); } inline double Norm(const Vec2d& arg) { return sqrt( arg * arg ); } inline Vec2d Normalize(const Vec2d& arg) { return arg / Norm(arg); }
Posted 20 June 2011 - 04:49 PM
Posted 20 June 2011 - 05:58 PM
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
GameDev.net™, the GameDev.net logo, and GDNet™ are trademarks of GameDev.net, LLC.