#OSG+VS#第五周

来源:互联网 发布:和平网络电视频道地址 编辑:程序博客网 时间:2024/04/30 23:57

成果总结:

1.修改光影初始化中的日期和时间为当前日期时间。

    QTime currenttime=QTime::currentTime();    QDate currentdate=QDate::currentDate();    osg::Vec3d sunPosition = ep->getSunPositionECEF(osgEarth::DateTime(currentdate.year(),currentdate.month(),currentdate.day(),currenttime.hour()-8+currenttime.minute()/60.0+currenttime.second()/3600.0));

    m_date.setYMD(currentdate.year(),currentdate.month(),currentdate.day());    m_time.setHMS(currenttime.hour(),currenttime.minute(),currenttime.second());

2.解决拖拽卡顿。

virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa){……switch(ea.getEventType()){case(osgGA::GUIEventAdapter::PUSH):if(ea.getButton()==1){……}return false;//将return true改为false}return false;}
其实教材中,代码后面的解释说了:“返回真,是不安全的操作,通常需要设置为假”。后来请教了师兄,虽然他说的没完全懂,也差不多懂个大概:

我的问题在于“返回”,而不是真假,因为handle是和bool变量,最终需要返回一个值,每一个case也需要返回一个值。

case后面返回假,才能不影响后续各类鼠标或键盘事件(我开始设为true,则只响应单击,会影响原有的拖拽功能,造成的表象是出现卡顿。)

整个handle返回假,才能让所有事件(除了鼠标键盘,还有滑轮等)响应,教材原话:“如果设置为真,那么处理完当前事件后,事件处理就不会再向下传递”。(我尝试设为false,导致单击拖拽放大缩小都不能响应。)

一句话小结:case后的false,让该事件不影响其他事件;handle的false让所有事件得以响应。
3.几次尝试:

①对于hit方法,尝试了shadowcaster->accept(iv),还是不对,尤其房屋上的点,几乎判断不出来。地面大致能区别,但不准确。

②卡顿改好后,差不多确定坐标转换没问题。调试中,发现太阳坐标有double变为float,是否是坐标值精度问题。后来画图发现,两点距离越远,精度影响越小。日地距离太远,影响不大。且我最后改为鼠标点为起点发射射线,这样影响更小。

③在网上搜索的过程中,有人提到“可能将模型自身节点纳入了碰撞检测”,这给了我灵感,可能这就是导致所有点在模型房屋上的鼠标点,判断结果都有unable(有model,有遮挡)。文中提到用model->setNodeMask(0x0)隐藏模型,避开自身节点。我尝试之后,进一步确认了确实将模型自身当当作了交点之一。

同时发现另一个问题:隐藏模型后,该模型的阴影了没有了。应该是insertGroup(shadowcaster,mRoot)的原因。【后来问了师姐,这样放方便管理,想要模型关闭阴影存在,可以通过改变shadowcaster中的参数完成。】

④因此,隐藏模型的方法,暂时不可取。想直接将最后一个交点不纳入循环,然额宝宝做不到。第二天又想到将鼠标点作为起点,这样第一个交点就是自身模型,然后用if…continue,跳出第一个循环,不继续判断有无模型。

4.暂定解决方法:

①判断是否遮挡。

通过大量测试总结==发现不论是地面还是模型房屋上,阴影里交点个数是0或者1个,没有阴影的地方交点个数大于1。所以连循坏都不需要了,两个if else搞定!

(多么重要的一个总结发现啊!说明即使不理解nodepath也不影响了。这说明在纸上写写画画,绝壁比脑海里飘着更有用啊!)

②计算日照量。

思路:根据以上,交点大于1,被遮挡,该时间间隔不计入日照时间;否则计入日照时间。

这里主要是时间转换问题。

我以一分钟为时间间隔,最终得到一天日照时间的总分钟数。要将其转换为几小时几分用以结果显示。固然可以用QString,输出“int小时int分钟”,但我想以“00:00”的形式显示。考虑再三,在网上找到了QDateTime dt = QDateTime::fromTime_t (秒数);,这是将总秒数转换成了从1970年1月1日00:00:00算起的时间,但它居然自动转成了北京时间…其实我就想要UTC的啊…然额又不能直接减8小时,因为总时间最大也就8小时。

又陷入继续寻找相关函数的漫漫路,最后综合网上的灵感和番茄助手的提示,在dt.中找到了toUTC!yes!

于是有了dt.toUTC().toString("yyyy-MM-dd hh:mm:ss").mid(11,5);,这样就截取到了其中的“hh:mm”哦~~

【还是存在少量问题,无阴影处可能出现2个交点。】

【问题,由于每分钟一次判断,一个点循环480次,场景中模型过多,导致计算速度下降明显。后续框选整个小区,影响更大,待优化。】


几点理解:

1.虽然叫做linesegment(线段),其实也都是射线,从起点向终点发射射线,且起点和终点都会被算作交点。

2.深入了解交点参数,有两种方式。一是iv.hit,二是for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();hitr != intersections.end();++hitr)  。

对hitlist等理解不够,目前用的是第二种,也是比较常见的方法。

3.在第二种方法中,几点理解:

①radio是交点与线段起点的距离和线段总长度的比例。

②nodepath。每个交点的nodepath,是从根节点开始走到交点的叶节点的路径(因为我这里写的mRoot->accept(iv))。

另外路径中,不是每个节点都有名字,所以使用教材中!(hitr->nodepath.back()->getName().empty())筛选过滤一部分交点的方法不可取。

4.交集测试(第一种)

Osg2.0以上版本中,已经使用了IntersectionVisitor代替了原有的IntersectVisitor类,新的类功能更强大。
基本类介绍:
线段:osg::LineSegment类,场景中的射线,包括两点,一个是线段的起点,一个是线段的终点,都为osg::vec3向量实例,当交集测试被触发时,它将检测射线的相交情况并执行相应的操作.
交点:osgUtil::Hit:这个类向程序员提供了获取交集检测的基本数据的方法。交点类包括一条射线与场景几何体相交的状态信息,尤为重要的是,它以vec3形式提供了局部和世界坐标的位置以及法线数据。它的成员方法getLocalIntersectPoint getLocalIntersectNormal getWorldIntersectPoint
getWorldIntersectNormal分别以osg::vec3作为返回值,返回局部/世界坐标的相交点/法线数值。
交点类表:osgUtil::IntersectVisitor::HitList:一条单一的线段可能与场景中的多个几何体实例产生交集。对于每一条参与交集测试的线段,系统均会产生一个列表。这个列表包含了所有交集测试产生的Hit实例,如果没有检测到交集,此列表为空。

交集访问器:osgUtil::IntersectVisitor,射线与场景中几何体的交集测试由交集访问器来创建并实现初始化。IntersectionVisitor类继承自NodeVisitor类,因此其创建和触发机制与NodeVisitor大致相似。访问器需要维护一个进行交集测试的线段列表,而对于其中的每一条线段,访问器都会创建一个交点列表(osgUtil::IntersectVisitor::HitList实例)。


问题:

1..h文件中,QMessageBox::information(this, "My Tittle", "none!")遇到“QMessageBox::information”: 4 个重载中没有一个可以转换所有参数类型

改为QMessageBox::information(0, "My Tittle", "none!");

参考:http://stackoverflow.com/questions/17773502/about-qt-messageboxwarning-overloading/

2.Qt中截取字符串

参考:http://www.cnblogs.com/onlycxue/archive/2012/10/30/2746902.html

3.Qt中整形转字符串,时间转换。

                QString s = QString::number(sum_minute);QDateTime dt = QDateTime::fromTime_t (sum_minute*60);QString sum_time=dt.toUTC().toString("yyyy-MM-dd hh:mm:ss").mid(11,5);QMessageBox::information(this, "title", sum_time+"  共"+s+"分钟");


下周目标:

0.老师对上周周报的建议:①是否能将太阳看作一个点;②高清光源模型,是点光源还是平行光源;③把osgearth光照阴影计算搞清楚。

1.不总结不知道啊,原来自己这周还是做了很多尝试的。虽然周一下午请假了,办完事玩了半天,略有愧疚感,但脑筋一直在运转,而且功能上差不多解决了。原来还担心两周都解决不了呢。给自己点个赞~\(≧▽≦)/~

2.单点日照量暂时到此为止,后面只有确定了日照标准才能做后续开发。

3.下一步是解决阴影自投影问题!!!啊啊啊!hin不简单啊。

显示、渲染、着色,可能跟这些有关,然而我基本不懂。还要完全看懂osg和osgearth自带的阴影算法,也许需要做必要修改。工程浩大!

但愿一个月能完成吧……

加油加油加油!!!


0 0