弯管机3D DEMO

昨天经过一些努力,把弯管机的管子加到了弯管机上面。添加了一些手工的弯管步骤,做了一个DEMO。

最后在其他非开发机上面运行的时候,出现了“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正此问题。”这个问题。上网查询,查到原来如此:
“……原来我在编译lib和exe文件的时候,一个选择Multi-threaded,一个选择Multi-threaded DLL, 最终造成了最终这样的结果。……”(引用:http://www.panzhishi.com/classyk/article.asp?id=4)

后来我用PE Explorer分别查看Multi-threaded和Multi-threaded DLL这两个选项生成的可执行文件,发现
Dependency有区别:
Multi-threaded DLL版本比Multi-threaded版本要多两个dll:msvcp80.dll msvcr80.dll,搜索后发现在WindowsWinSxS目录下,应该是vc crt的运行库。在其他电脑上没有这两个库,所以会出现这样的问题。

经过尝试解决办法有:

  • 重新编译应用程序,保证所有的库和编译的程序选择Multi-threaded。
  • 安装.Net Framework 2.0

下面是我的弯管机的3D演示。[已经失效]

Flash动画
在线播放

Yeah!

骑车来回30公里,帮女生修电脑 。可能是氧气比较充足,晚上写程序思路清晰,问题一个一个顺利解决!现在毕业设计已经完成了50%以上了,高兴啊。有空把管子弄上机床,开始加工:)
. 永远记住,仿射变换是左乘,OpenGL是右乘。保持头脑清晰,做图形学最重要的是矩阵变换要正确。

从父对象到子对象的转换:

childMatrix=parentMatrix*transformMatrix  ====>
transformMatrix=Inverse(parentMatrix)*childMatrix
  • 树的数据结构很重要,需要更加熟练,经常在树的遍历上出点小问题。
  • 用多种手段进行调试。调试的方法的选择直接关系到找到和解决问题的速度。
  • 经常锻炼,心急的时候出去走走比较好。大脑是需要氧气的。

最终用自己写的程序的渲染效果,各个部件能够运动的,还有碰撞检测。

黄龙溪

本昨天说去爬“长城”的,考虑到奶奶身体不好不能去,所以改航线到黄龙溪了。
黄龙溪给我的印象仅仅停留在小时候,依稀记得茶馆里面的热闹,吃着黑芝麻膏的我,坐渡船的激动,还有老黄葛树。十几年没有再去过那里,去年十月国情的时候从那儿路过,只是天色已晚,就匆匆回家了。今天再来重游黄龙溪,再来拾起一些小时候的记忆。
如今的黄龙溪已经是改造成旅游景点了,很多古建筑已经翻新,昔日的渡船码头已经变成了供观光游玩的码头了,不再像以前用于汽车过河用。两河分叉处那颗古树周围已经重新修建,完全没有了旧有的记忆。
老街已经不复存在,全被改造过了。感觉是人造的“复古”。说起现在的“古镇”,到处都是一个样,建筑物也是差不多,卖的特色东西也不多,感觉是为了“复古”而“复古”,越来越抹杀了古镇原本的特色。看来想真正的看到古镇,还得多跑跑腿,到远处的农村去看看。
图:行到水穷处,坐看云起时。刚进门不久的一个长廊上,每个柱子上面都有这样的雕刻。

图:导游图。每到一个地方,我就喜欢把导游图拍下来。一来免得走丢了,二来可以知道哪些地方可以去。

图:茶庄。我爸说以前在这里喝过茶的,我倒是没有什么映像了,只是隐约记得有这样一个茶庄。

图:东寨门。这个是后来修的。

图:停泊的船只。左上那颗树已经有很长的年龄了,算是黄龙溪的标志,现在围起来了,反而觉得不爽。

图:街道。有些雾气。

图:好不容易找到一处“老古董”

图:以前在我家附近这样的墙很常见,倍感亲切

图:黄葛树。黄龙溪这样的大树很多,也算是一个标志

图:全景。注意江面。比较搞笑的是从左边流过来的水是黄的,而中间河道流过来的水就是黑的。黑的水是成都上游流下来的:)

图:返程路上,手工编制草帽。听老奶奶说编织2米,才1角钱。还是比较辛苦的喔。其实感觉老年人这样活动活动还是对身心健康有益,只是还是要劳逸结合,不要坐久了。

看完了我的随拍,有兴趣在多了解一些么?见这里的链接:
http://www.inkcn.com/v8/ReadNews.asp?NewsID=636
晚上找了很久,原来机动车的渡船已经找不到图片了,现在留下的只是河水静静的淌,少了人流车流,变得冷清多了。

碰撞检测&机床模型

下午优化了程序流程,缓冲了一些东西,使碰撞检测的速度大大提高。现在4个57600面的运动茶壶相互进行碰撞检测(一帧6次检测),线框模式下可以维持在20FPS左右(注:线框模式在非专业显卡上速度较慢)。成绩已经比较满意了,至少足够应用了,工控机P4 2.8+512内存已经足够了。但是麻烦的是不知道集成显卡的性能好不好。以后要测试在虚拟机下面的成绩,还有其他低配置电脑上的运行效率。

图:4个57600面的茶壶的碰撞检测。红色的地方是检测到的碰撞中的第一个三角形,太小了已经很难分辨了。
collision.jpg

优化完碰撞检测以后,就出去散步了。和老爸走了几公里的路,晒晒太阳,多温馨的:)

晚上回来就没有怎么弄编程了。就开始制作机床的模型,毕竟实用当中是以实际机床模型作为碰撞检测的基础的。照着一个参考机床用3DSMAX做了一个,慢慢熟悉3DSMAX的操作,还不错,做出来还像个样子。

图:我做的弯管机机床
machine.jpg

明天还要出去耍喔,到洛带,爬“长城”!

学习心得

感冒接近尾声了,真实感觉身体素质那么差喔,一天吃那么多东西都是浪费…………最近又重新开始弄弯管机的玩意儿了,有些学习心得和实际操作心得,留个纪录:
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"<
}

这样正确。

但是遇到这样的情况:

string name="Hello";
string name1="Hello";
name.resize(10);
if(name.compare(name1)==0)
{
cout<<"Identical"<
}

如果不注意其实用了resize以后,name就变成了Hello\n\n\n\n\n,结果和name1比较,结果不会是相同的(VS2005编译结果)。需要注意!可能是string类的compare函数实现上不以\n作为结尾而是以实际长度作为长度判断标准(瞎猜,要看看相应的文献再说)

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、闲话

要早点睡觉,身体那么差了,唉~~~~~~~~~睡觉!