Sprite3DWithOBBPerfromanceTest::Sprite3DWithOBBPerfromanceTest()
{
autolistener=EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan=CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesBegan,
this
);
listener->onTouchesEnded=CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesEnded,
this
);
listener->onTouchesMoved=CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesMoved,
this
);
autos=Director::getInstance()->getWinSize();
initDrawBox();
addNewSpriteWithCoords(Vec2(s.width/2,s.height/2));
MenuItemFont::setFontName(
"fonts/arial.ttf"
);
MenuItemFont::setFontSize(65);
autodecrease=MenuItemFont::create(
"-"
,CC_CALLBACK_1(Sprite3DWithOBBPerfromanceTest::delOBBCallback,
this
));
decrease->setColor(Color3B(0,200,20));
autoincrease=MenuItemFont::create(
"+"
,CC_CALLBACK_1(Sprite3DWithOBBPerfromanceTest::addOBBCallback,
this
));
increase->setColor(Color3B(0,20));
automenu=Menu::create(decrease,increase,nullptr);
menu->alignItemsHorizontally();
menu->setPosition(Vec2(s.width/2,s.height-65));
addChild(menu,1);
TTFConfigttfCount(
"fonts/MarkerFelt.ttf"
,30);
_labelCubeCount=Label::createWithTTF(ttfCount,
"0cubes"
);
_labelCubeCount->setColor(Color3B(0,20));
_labelCubeCount->setPosition(Vec2(s.width/2,s.height-90));
addChild(_labelCubeCount);
_hasCollider=
false
;
addOBBCallback(nullptr);
scheduleUpdate();
}
std::stringSprite3DWithOBBPerfromanceTest::title()
const
{
return
"OBBCollisonPerfromanceTest"
;
}
std::stringSprite3DWithOBBPerfromanceTest::subtitle()
const
{
return
""
;
}
void
Sprite3DWithOBBPerfromanceTest::addNewOBBWithCoords(Vec2p)
{
Vec3extents=Vec3(10,10,10);
AABBaabb(-extents,extents);
autoobb=OBB(aabb);
obb._center=Vec3(p.x,p.y,0);
_obb.push_back(obb);
}
void
Sprite3DWithOBBPerfromanceTest::onTouchesBegan(
const
std::vector<Touch*>&touches,Event*event)
{
for
(autotouch:touches)
{
autolocation=touch->getLocationInView();
if
(_obb.size()>0)
{
_intersetList.clear();
Rayray;
calculateRayByLocationInView(&ray,location);
for
(
int
i=0;i<_obb.size();i++)
{
if
(ray.intersects(_obb[i]))
{
_intersetList.insert(i);
return
;
}
}
}
}
}
void
Sprite3DWithOBBPerfromanceTest::onTouchesEnded(
const
std::vector<Touch*>&touches,Event*event)
{
}
void
Sprite3DWithOBBPerfromanceTest::onTouchesMoved(
const
std::vector<Touch*>&touches,Event*event)
{
for
(autotouch:touches)
{
autolocation=touch->getLocation();
for
(
int
i=0;i<_obb.size();i++)
{
if
(_intersetList.find(i)!=_intersetList.end())
_obb[i]._center=Vec3(location.x,location.y,0);
}
}
}
void
Sprite3DWithOBBPerfromanceTest::update(
float
dt)
{
char
szText[16];
sprintf
(szText,
"%lucubes"
,_obb.size());
_labelCubeCount->setString(szText);
if
(_drawDebug)
{
_drawDebug->clear();
Mat4mat=_sprite->getNodeToWorldTransform();
mat.getRightVector(&_obbt._xAxis);
_obbt._xAxis.normalize();
mat.getUpVector(&_obbt._yAxis);
_obbt._yAxis.normalize();
mat.getForwardVector(&_obbt._zAxis);
_obbt._zAxis.normalize();
_obbt._center=_sprite->getPosition3D();
Vec3corners[8]={};
_obbt.getCorners(corners);
_drawDebug->drawCube(corners,Color4F(0,1));
}
if
(_obb.size()>0)
{
_drawOBB->clear();
for
(
int
i=0;i<_obb.size();i++)
{
Vec3corners[8]={};
_obb[i].getCorners(corners);
_drawOBB->drawCube(corners,_obbt.intersects(_obb[i])?Color4F(1,1):Color4F(0,1));
}
}
}
void
Sprite3DWithOBBPerfromanceTest::initDrawBox()
{
_drawOBB=DrawNode3D::create();
addChild(_drawOBB);
}
void
Sprite3DWithOBBPerfromanceTest::addNewSpriteWithCoords(Vec2p)
{
std::stringfileName=
"Sprite3DTest/tortoise.c3b"
;
autosprite=Sprite3D::create(fileName);
sprite->setScale(0.1f);
autos=Director::getInstance()->getWinSize();
sprite->setPosition(Vec2(s.width*4.f/5.f,s.height/2.f));
addChild(sprite);
_sprite=sprite;
autoanimation=Animation3D::create(fileName);
if
(animation)
{
autoanimate=Animate3D::create(animation,1.933f);
sprite->runAction(RepeatForever::create(animate));
}
_moveAction=MoveTo::create(4.f,s.height/2.f));
_moveAction->retain();
autoseq=Sequence::create(_moveAction,CallFunc::create(CC_CALLBACK_0(Sprite3DWithOBBPerfromanceTest::reachEndCallBack,nullptr);
seq->setTag(100);
sprite->runAction(seq);
AABBaabb=_sprite->getAABB();
_obbt=OBB(aabb);
_drawDebug=DrawNode3D::create();
addChild(_drawDebug);
}
void
Sprite3DWithOBBPerfromanceTest::reachEndCallBack()
{
_sprite->stopActionByTag(100);
autoinverse=(MoveTo*)_moveAction->reverse();
inverse->retain();
_moveAction->release();
_moveAction=inverse;
autorot=RotateBy::create(1.0f,0.f));
autoseq=Sequence::create(rot,nullptr);
seq->setTag(100);
_sprite->runAction(seq);
}
void
Sprite3DWithOBBPerfromanceTest::addOBBCallback(Ref*sender)
{
addOBBWithCount(10);
}
void
Sprite3DWithOBBPerfromanceTest::addOBBWithCount(
float
value)
{
for
(
int
i=0;i<value;i++)
{
Vec2randompos=Vec2(CCRANDOM_0_1()*Director::getInstance()->getWinSize().width,CCRANDOM_0_1()*Director::getInstance()->getWinSize().height);
Vec3extents=Vec3(10,10);
AABBaabb(-extents,extents);
autoobb=OBB(aabb);
obb._center=Vec3(randompos.x,randompos.y,0);
_obb.push_back(obb);
}
}
void
Sprite3DWithOBBPerfromanceTest::delOBBCallback(Ref*sender)
{
delOBBWithCount(10);
}
void
Sprite3DWithOBBPerfromanceTest::delOBBWithCount(
float
value)
{
if
(_obb.size()>=10)
{
_obb.erase(_obb.begin(),_obb.begin()+value);
_drawOBB->clear();
}
else
return
;
}
void
Sprite3DWithOBBPerfromanceTest::unproject(
const
Mat4&viewProjection,
const
Size*viewport,Vec3*src,Vec3*dst)
{
assert
(dst);
assert
(viewport->width!=0.0f&&viewport->height!=0.0f);
Vec4screen(src->x/viewport->width,((viewport->height-src->y))/viewport->height,src->z,1.0f);
screen.x=screen.x*2.0f-1.0f;
screen.y=screen.y*2.0f-1.0f;
screen.z=screen.z*2.0f-1.0f;
viewProjection.getInversed().transformVector(screen,&screen);
if
(screen.w!=0.0f)
{
screen.x/=screen.w;
screen.y/=screen.w;
screen.z/=screen.w;
}
dst->set(screen.x,screen.y,screen.z);
}
void
Sprite3DWithOBBPerfromanceTest::calculateRayByLocationInView(Ray*ray,
const
Vec2&location)
{
autodir=Director::getInstance();
autoview=dir->getWinSize();
Mat4mat=dir->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
mat=dir->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
Vec3src=Vec3(location.x,-1);
Vec3nearPoint;
unproject(mat,&view,&src,&nearPoint);
src=Vec3(location.x,1);
Vec3farPoint;
unproject(mat,&farPoint);
Vec3direction;
Vec3::subtract(farPoint,nearPoint,&direction);
direction.normalize();
ray->_origin=nearPoint;
ray->_direction=direction;
}