_Minimap.h
Code: Select all
class MiniMapObject;
class MiniMap : public IGUIElement
{
rectf MovementRect;
ISceneManager* Smgr;
core::list<MiniMapObject*> MMObjects;
public :
MiniMap(ISceneManager*, IGUIEnvironment*, IGUIElement* parent, s32 id, rect<s32> MiniMapRect, aabbox3df MovementBox);
~MiniMap();
IVideoDriver* GetDriver(void) { return Environment->getVideoDriver(); }
const rectf& GetMovementRect(void) { return MovementRect; }
void Add(MiniMapObject* obj) { MMObjects.push_back(obj); }
vector2df GetMovementSpacePosition(const vector2di& MinimapSpace);
void Remove(MiniMapObject* obj);
void draw(void);
};
class MiniMapObject
{
friend MiniMap;
protected :
bool Minimap_visible;
SColor Minimap_color;
ITexture* Minimap_image;
dimension2df ObjectSize;
MiniMap* Minimap_Parent;
public :
MiniMapObject(const MiniMapObject&);
MiniMapObject(MiniMap* Parent, const dimension2df& objectsizeinprecent, const SColor& color);
MiniMapObject(MiniMap* Parent, const dimension2df& objectsizeinprecent, const char* image);
~MiniMapObject();
virtual void DrawMiniMapObject();
recti GetMinimapSpaceRect();
bool VisibleOnMinimap() const { return Minimap_visible; }
void SetMinimapVisibility (bool val) { Minimap_visible = val; }
virtual vector2df GetPosition(void) const = 0;
};Code: Select all
#include "irrlicht.h"
using namespace irr;
using namespace video;
using namespace core;
using namespace gui;
using namespace scene;
#include "_Minimap.h"
vector2di Vector_SpaceToMinimap(const vector2df& posf, const rectf& movement, f32 width_scalfactor, f32 height_scalfactor)
{
return vector2di((s32)( (posf.X - movement.UpperLeftCorner.X) * width_scalfactor + 0.5f),
(s32)(-(posf.Y + movement.UpperLeftCorner.Y) * height_scalfactor + 0.5f));
}
MiniMap::MiniMap(ISceneManager* smgr, IGUIEnvironment* environment, IGUIElement* parent, s32 id, recti MiniMapRect, aabbox3df MovementBox)
: IGUIElement(EGUIET_ELEMENT, environment, parent ? parent : environment->getRootGUIElement(), id, MiniMapRect), Smgr(smgr)
{
MovementRect = rectf(MovementBox.MinEdge.X, MovementBox.MinEdge.Z, MovementBox.MaxEdge.X, MovementBox.MaxEdge.Z);
}
MiniMap::~MiniMap()
{
for(core::list<MiniMapObject*>::Iterator it = MMObjects.begin(); it != MMObjects.end(); it++)
(*it)->Minimap_Parent = NULL;
}
vector2df MiniMap::GetMovementSpacePosition(const vector2di& MinimapSpace)
{
vector2df ret((f32)MinimapSpace.X, (f32)MinimapSpace.Y);
ret.X = ret.X * MovementRect.getWidth() / getAbsolutePosition().getWidth() + MovementRect.UpperLeftCorner.X;
ret.Y = -ret.Y * MovementRect.getHeight() / getAbsolutePosition().getHeight() - MovementRect.UpperLeftCorner.Y;
return ret;
}
void MiniMap::Remove(MiniMapObject* obj)
{
for(core::list<MiniMapObject*>::Iterator it = MMObjects.begin(); it != MMObjects.end(); it++)
{
if(obj == *it)
{
MMObjects.erase(it);
break;
}
}
}
void MiniMap::draw(void)
{
if(!IsVisible)
return;
//DEBUG
GetDriver()->draw2DRectangle(0xFF000000, getAbsolutePosition());
for(core::list<MiniMapObject*>::Iterator it = MMObjects.begin(); it != MMObjects.end(); it++)
(*it)->DrawMiniMapObject();
const SViewFrustum* view = Smgr->getActiveCamera()->getViewFrustum();
f32 width_scalfactor = getAbsolutePosition().getWidth() / GetMovementRect().getWidth();
f32 height_scalfactor = getAbsolutePosition().getHeight() / GetMovementRect().getHeight();
u16 index = 0;
plane3df movementplanes[4];
plane3df plane(0,0,0,0,1,0);
vector3df points[16];
vector3df conepoints[4];
vector2di linepoints[8];
vector3df a(GetMovementRect().LowerRightCorner.X, 0, GetMovementRect().LowerRightCorner.Y);
vector3df b(GetMovementRect().UpperLeftCorner.X, 0, GetMovementRect().UpperLeftCorner.Y);
movementplanes[0].setPlane(a, vector3df(1,0,0));
movementplanes[1].setPlane(a, vector3df(0,0,1));
movementplanes[2].setPlane(b, vector3df(1,0,0));
movementplanes[3].setPlane(b, vector3df(0,0,1));
points[0] = view->cameraPosition;
points[1] = view->getFarLeftUp();
points[2] = view->cameraPosition;
points[3] = view->getFarLeftDown();
points[4] = view->cameraPosition;
points[5] = view->getFarRightDown();
points[6] = view->cameraPosition;
points[7] = view->getFarRightUp();
points[8] = view->getFarRightDown();
points[9] = view->getFarRightUp();
points[10] = view->getFarRightUp();
points[11] = view->getFarLeftUp();
points[12] = view->getFarLeftUp();
points[13] = view->getFarLeftDown();
points[14] = view->getFarLeftDown();
points[15] = view->getFarRightDown();
for(u16 counter = 0; counter < 16; counter+=2)
{
vector3df tempvec;
if(plane.getIntersectionWithLimitedLine(points[counter], points[counter+1], tempvec))
{
if(index == 4)
return;
conepoints[index] = tempvec;
index++;
}
}
for(u16 counter = 0; counter < 4; counter++)
{
vector2df temppoint(conepoints[counter].X, conepoints[counter].Z);
if(MovementRect.isPointInside(temppoint))
{
linepoints[counter] = Vector_SpaceToMinimap(temppoint, MovementRect, width_scalfactor, height_scalfactor);
linepoints[counter+4] = linepoints[counter];
}
else
{
//correct the point position
vector3df A = conepoints[counter];
vector3df B = conepoints[(counter+1)%4];
vector3df C = conepoints[counter];
vector3df D = conepoints[(counter+3)%4];
for(u16 i = 0; i < 4; i++)
{
vector3df temppoint;
if(movementplanes[i].getIntersectionWithLimitedLine(A, B, temppoint))
A = temppoint;
if(movementplanes[i].getIntersectionWithLimitedLine(C, D, temppoint))
C = temppoint;
}
linepoints[counter] = Vector_SpaceToMinimap(vector2df(A.X, A.Z), MovementRect, width_scalfactor, height_scalfactor);
linepoints[counter+4] = Vector_SpaceToMinimap(vector2df(C.X, C.Z), MovementRect, width_scalfactor, height_scalfactor);
}
}
for(u16 counter = 0; counter < 4; counter++)
{
vector2di start = linepoints[counter] + getAbsolutePosition().UpperLeftCorner;
vector2di end = linepoints[(counter+1)%4+4] + getAbsolutePosition().UpperLeftCorner;
if(getAbsolutePosition().isPointInside(start) && getAbsolutePosition().isPointInside(end))
GetDriver()->draw2DLine(start, end);
}
}
MiniMapObject::MiniMapObject(const MiniMapObject &e)
: Minimap_visible(e.Minimap_visible), Minimap_color(e.Minimap_color), Minimap_image(e.Minimap_image), Minimap_Parent(e.Minimap_Parent), ObjectSize(e.ObjectSize)
{
if(Minimap_Parent)
Minimap_Parent->Add(this);
}
MiniMapObject::MiniMapObject(MiniMap* map, const dimension2df& sizeinpercent, const SColor &_color)
: Minimap_visible(true), Minimap_color(_color), Minimap_image(NULL), Minimap_Parent(map), ObjectSize(sizeinpercent)
{
if(Minimap_Parent)
Minimap_Parent->Add(this);
}
MiniMapObject::MiniMapObject(MiniMap* map, const dimension2df& sizeinpercent, const char* image)
: Minimap_visible(true), Minimap_color(0), Minimap_image(NULL), Minimap_Parent(map), ObjectSize(sizeinpercent)
{
if(Minimap_Parent)
Minimap_Parent->Add(this);
Minimap_image = Minimap_Parent->GetDriver()->getTexture(image);
}
MiniMapObject::~MiniMapObject()
{
if(Minimap_Parent)
Minimap_Parent->Remove(this);
}
void MiniMapObject::DrawMiniMapObject()
{
if(!Minimap_visible || !Minimap_Parent)
return;
recti drawrc = GetMinimapSpaceRect() + Minimap_Parent->getAbsolutePosition().UpperLeftCorner;
if(Minimap_image)
Minimap_Parent->GetDriver()->draw2DImage(Minimap_image, drawrc, recti(vector2di(), Minimap_image->getSize()));
else
Minimap_Parent->GetDriver()->draw2DRectangle(Minimap_color, drawrc, &Minimap_Parent->getAbsolutePosition());
}
recti MiniMapObject::GetMinimapSpaceRect(void)
{
f32 width_scalfactor = Minimap_Parent->getAbsolutePosition().getWidth() / Minimap_Parent->GetMovementRect().getWidth();
f32 height_scalfactor = Minimap_Parent->getAbsolutePosition().getHeight() / Minimap_Parent->GetMovementRect().getHeight();
vector2di pos = Vector_SpaceToMinimap(GetPosition(), Minimap_Parent->GetMovementRect(), width_scalfactor, height_scalfactor);
return recti( pos.X - (s32)(ObjectSize.Width * Minimap_Parent->getAbsolutePosition().getWidth()),
pos.Y - (s32)(ObjectSize.Height * Minimap_Parent->getAbsolutePosition().getHeight()),
pos.X + (s32)(ObjectSize.Width * Minimap_Parent->getAbsolutePosition().getWidth()),
pos.Y + (s32)(ObjectSize.Height * Minimap_Parent->getAbsolutePosition().getHeight()));
}
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace video;
using namespace core;
using namespace gui;
using namespace scene;
#include "_Minimap.h"
struct Object : public MiniMapObject
{
ISceneNode* cube;
Object(ISceneManager *Smgr, vector3df pos, MiniMap* map)
: MiniMapObject(map, dimension2df(0.05f,0.05f), 0xFF00FF00)
{
cube = Smgr->addCubeSceneNode(10.f, 0,-1,pos);
}
vector2df GetPosition(void) const { return vector2df(cube->getPosition().X, cube->getPosition().Z); }
};
void main()
{
IrrlichtDevice *irr = createDevice( video::EDT_OPENGL, dimension2du(1024,786));
IVideoDriver *Video = irr->getVideoDriver();
ISceneManager *Smgr = irr->getSceneManager();
IGUIEnvironment *Gui = irr->getGUIEnvironment();
Smgr->addCameraSceneNodeFPS()->setPosition(vector3df(0,200,-10));
aabbox3df MovementBox(-1000,-100,-1000, 1000, 100, 1000);
MiniMap map(Smgr, Gui, 0, -1, recti(10,10,150,150), MovementBox);
array<Object> testobjects;
srand(irr->getTimer()->getTime());
for(unsigned counter = 0; counter < 10; counter++)
{
vector3df pos;
pos.X = MovementBox.MinEdge.X + MovementBox.getExtent().X * (rand() % 1000) / 1000.0f;
pos.Y = MovementBox.MinEdge.X + MovementBox.getExtent().Y * (rand() % 1000) / 1000.0f;
pos.Z = MovementBox.MinEdge.X + MovementBox.getExtent().Z * (rand() % 1000) / 1000.0f;
testobjects.push_back(Object(Smgr, pos, &map));
}
while( irr->run() )
{
Video->beginScene( true, true, video::SColor(255,100,101,140) );
Smgr->drawAll();
Gui->drawAll();
Video->endScene();
}
irr->drop();
} 