/* * MapView.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "MapView.h" #include "TopView.h" #include #include #include #include #include #include #include #include namespace ZoomEdit { namespace View { void MapView::setMainView(TopView *mainView0) { mainView = mainView0; if(mainViewUpdate) mainViewUpdate.disconnect(); if(mainView) mainViewUpdate = mainView->signalUpdate().connect(signalUpdate()); } void MapView::init() { glClearColor(0, 0, 0, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); } void MapView::resize(float width, float height) { if(width == viewWidth && height == viewHeight) return; viewWidth = width; viewHeight = height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(width != 0 && height != 0) glScalef(2.0f/width, -2.0f/height, 1); signalUpdate().emit(); } void MapView::zoom(int zoom, float, float) { if(!mainView) return; mainView->zoom(zoom, 0, 0); } void MapView::move(float x, float y, unsigned int state) { if(!mainView) return; if(!(state & GDK_BUTTON1_MASK)) return; mainView->setXCenter(mainView->getXCenter() - x/scale); mainView->setYCenter(mainView->getYCenter() - y/scale); } void MapView::click(float x, float y, unsigned int button) { if(!mainView || button != 1) return; mainView->setXCenter(xCenter + x/scale); mainView->setYCenter(yCenter + y/scale); } void MapView::render() { glClear(GL_COLOR_BUFFER_BIT); if(!mainView || !mainView->getInstance()->getLevel()) return; float minX, maxX, minY, maxY; getBounds(&minX, &maxX, &minY, &maxY); xCenter = (minX+maxX)/2; yCenter = (minY+maxY)/2; float width = maxX-minX, height=maxY-minY; if(width == 0 || height == 0) return; scale = std::min(viewWidth/width, viewHeight/height)*0.75f; glMatrixMode(GL_MODELVIEW); glPushMatrix(); glScalef(scale, scale, 1); glTranslatef(-xCenter, -yCenter, 0); const std::list &rooms = mainView->getInstance()->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) TopView::renderRoom(*room, (*room == mainView->getInstance()->getSelectedRoom())); float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter(); float mainScale = mainView->getScale(); float mainWidth = mainView->getWidth()/mainScale, mainHeight = mainView->getHeight()/mainScale; glColor4f(0.7f, 0.7f, 0.7f, 0.3f); glBegin(GL_POLYGON); glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); glEnd(); glColor4f(0.7f, 0.7f, 0.7f, 0.7f); glLineWidth(1.0f); glBegin(GL_LINE_LOOP); glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); glEnd(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } void MapView::getBounds(float *minX, float *maxX, float *minY, float *maxY) { if(minX) *minX = 0; if(maxX) *maxX = 0; if(minY) *minY = 0; if(maxY) *maxY = 0; if(!mainView || !mainView->getInstance()->getLevel()) return; const std::list &rooms = mainView->getInstance()->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { const std::list &triangles = (*room)->getTriangles(); for(std::list::const_iterator t = triangles.begin(); t != triangles.end(); ++t) { const vmml::vec3f &v1 = (*t)->getVertex(0), &v2 = (*t)->getVertex(1), &v3 = (*t)->getVertex(2); if(minX) *minX = std::min(std::min(*minX, v1.x()), std::min(v2.x(), v3.x())); if(maxX) *maxX = std::max(std::max(*maxX, v1.x()), std::max(v2.x(), v3.x())); if(minY) *minY = std::min(std::min(*minY, v1.z()), std::min(v2.z(), v3.z())); if(maxY) *maxY = std::max(std::max(*maxY, v1.z()), std::max(v2.z(), v3.z())); } } } } }