学习心得
感冒接近尾声了,真实感觉身体素质那么差喔,一天吃那么多东西都是浪费~~~~~最近又重新开始弄弯管机的玩意儿了,有些学习心得和实际操作心得,留个纪录:
1、关于矩阵乘法
OpenGL规定,最后定义的变换最先应用,每一步操作,都在CMT再右乘一个矩阵。所以坐标架原点p经过放射变换到q,公式如下:
q=M1*M2*M3*M4*p
其中M1为第一次变换,M2为第二次,以此类推。
特别要搞清楚到底是右乘还是左乘。取决于你是在移动坐标架还是在移动点。
如果是移动点,坐标系不变,则是:
q=M4*M3*M2*M1*p
相关文章参见《交互式计算机图形学——基于OpenGL的自顶向下方法(第三版)》P136和P145。
2、关于RAPID碰撞检测的调试
这个碰撞检测库需要你提供变换矩阵(tMatrix)和一个包含模型三角形的一个类的实例(model)。model比较好构建,只需要把模型三角形添加进去即可。tMatrix难度较大,需要做矩阵的乘法,往往这个不对会造成碰撞检测的失败。为了真实的看到碰撞检测是否正确,可以:
glPushMatrix();
glLoadIdentity();
glTranslate(tMatrix);
model.RenderTriangles();
glPopMatrix();
另外可以将碰撞检测所检测到的碰撞三角形显示出来,以重点测试tMatrix变换是否正确。
3、关于程序的一些设计
试验阶段,不必要一定遵循面向对象的一些设计思路,这样反而会弄得很麻烦。前段时间一直想用面向对象的设计思路来封装对象,结果后来一旦发现整体思路不正确,又要改很多很多,真的很麻烦。还不如面向过程,不管是书写还是调试都会有一定的速度优势。而可能更好的一面在于,万一方案不行,改动的时候会方便很多。举个例子:
比如对于一个类的名字:
class A{
public:
string GetName();
void SetName(const string* name);
private:
string name;
}
然后需要写对应的函数。
还不如直接
class A{
public:
string name;
}
虽然暴露了成员,但是给调试和写测试程序带来了很多方便。所以,凡是不要绝对化,该用什么的时候还是用什么比较好。
4、被骗
问题来自于3ds文件的Node的名字。他的名字只有10个字符长,但是3dsmax的max中却可以有很长的名字。
所以如果我需要调入GeoSphere01,其实在3ds文件中,只存在名字为GeoSphere0的Node。所以我想直接把Name调整大小成10就是了:
string name="GeoSphere01";
string name1="GeoSphere0";
name.resize(10);
if(name.compare(name1)==0)
{
cout<<"Identical"<<endl;
}
这样正确。
但是遇到这样的情况:
string name="Hello";
string name1="Hello";
name.resize(10);
if(name.compare(name1)==0)
{
cout<<"Identical"<<endl;
}
如果不注意其实用了resize以后,name就变成了Hello\0\0\0\0\0,结果和name1比较,结果不会是相同的(VS2005编译结果)。需要注意!可能是string类的compare函数实现上不以\0作为结尾而是以实际长度作为长度判断标准(瞎猜,要看看相应的文献再说)
5、简单测试内存是否泄漏
简单来说内存泄漏就是new了忘记delete,占用了内存。往往这些在于一个类的实例执行某些函数的时候new了一些东西,而忘记了在析构函数里面删除。
那么如何测试到底有没有泄漏呢?我的简单方法如下:
for(int i=0;i<10000;i++)
{
CObj obj1=new CObj();
obj1.doSomeTask();
delete obj1;
}
如果忘记了删除的话,你会看到任务管理器里面程序占用了大量的内存。这时候就说明obj1确实存在泄漏问题。如果要确定到底是什么原因造成的,可以在执行这段语句之前纪录下内存使用mem1,然后执行完了看看内存使用mem2。然后(mem2-mem1)/10000就是每一次new的大小,这样顺藤摸瓜总会找到一些没有delete的东西。
当然,更好的办法还是用专用工具。但现在对于我来说还没有用上:)
6、闲话
要早点睡觉,身体那么差了,唉~~~~~~~~~睡觉!
1、关于矩阵乘法
OpenGL规定,最后定义的变换最先应用,每一步操作,都在CMT再右乘一个矩阵。所以坐标架原点p经过放射变换到q,公式如下:
q=M1*M2*M3*M4*p
其中M1为第一次变换,M2为第二次,以此类推。
特别要搞清楚到底是右乘还是左乘。取决于你是在移动坐标架还是在移动点。
如果是移动点,坐标系不变,则是:
q=M4*M3*M2*M1*p
相关文章参见《交互式计算机图形学——基于OpenGL的自顶向下方法(第三版)》P136和P145。
2、关于RAPID碰撞检测的调试
这个碰撞检测库需要你提供变换矩阵(tMatrix)和一个包含模型三角形的一个类的实例(model)。model比较好构建,只需要把模型三角形添加进去即可。tMatrix难度较大,需要做矩阵的乘法,往往这个不对会造成碰撞检测的失败。为了真实的看到碰撞检测是否正确,可以:
glPushMatrix();
glLoadIdentity();
glTranslate(tMatrix);
model.RenderTriangles();
glPopMatrix();
另外可以将碰撞检测所检测到的碰撞三角形显示出来,以重点测试tMatrix变换是否正确。
3、关于程序的一些设计
试验阶段,不必要一定遵循面向对象的一些设计思路,这样反而会弄得很麻烦。前段时间一直想用面向对象的设计思路来封装对象,结果后来一旦发现整体思路不正确,又要改很多很多,真的很麻烦。还不如面向过程,不管是书写还是调试都会有一定的速度优势。而可能更好的一面在于,万一方案不行,改动的时候会方便很多。举个例子:
比如对于一个类的名字:
class A{
public:
string GetName();
void SetName(const string* name);
private:
string name;
}
然后需要写对应的函数。
还不如直接
class A{
public:
string name;
}
虽然暴露了成员,但是给调试和写测试程序带来了很多方便。所以,凡是不要绝对化,该用什么的时候还是用什么比较好。
4、被骗
问题来自于3ds文件的Node的名字。他的名字只有10个字符长,但是3dsmax的max中却可以有很长的名字。
所以如果我需要调入GeoSphere01,其实在3ds文件中,只存在名字为GeoSphere0的Node。所以我想直接把Name调整大小成10就是了:
string name="GeoSphere01";
string name1="GeoSphere0";
name.resize(10);
if(name.compare(name1)==0)
{
cout<<"Identical"<<endl;
}
这样正确。
但是遇到这样的情况:
string name="Hello";
string name1="Hello";
name.resize(10);
if(name.compare(name1)==0)
{
cout<<"Identical"<<endl;
}
如果不注意其实用了resize以后,name就变成了Hello\0\0\0\0\0,结果和name1比较,结果不会是相同的(VS2005编译结果)。需要注意!可能是string类的compare函数实现上不以\0作为结尾而是以实际长度作为长度判断标准(瞎猜,要看看相应的文献再说)
5、简单测试内存是否泄漏
简单来说内存泄漏就是new了忘记delete,占用了内存。往往这些在于一个类的实例执行某些函数的时候new了一些东西,而忘记了在析构函数里面删除。
那么如何测试到底有没有泄漏呢?我的简单方法如下:
for(int i=0;i<10000;i++)
{
CObj obj1=new CObj();
obj1.doSomeTask();
delete obj1;
}
如果忘记了删除的话,你会看到任务管理器里面程序占用了大量的内存。这时候就说明obj1确实存在泄漏问题。如果要确定到底是什么原因造成的,可以在执行这段语句之前纪录下内存使用mem1,然后执行完了看看内存使用mem2。然后(mem2-mem1)/10000就是每一次new的大小,这样顺藤摸瓜总会找到一些没有delete的东西。
当然,更好的办法还是用专用工具。但现在对于我来说还没有用上:)
6、闲话
要早点睡觉,身体那么差了,唉~~~~~~~~~睡觉!