//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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 2 of the License, or // (at your option) any later version. // // Scorched3D 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 Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include <3dsparse/ModelRenderer.h> #include #include #include #include #include // For porting MissileMesh::MissileMesh(Model &missile) : innerScale_(1.0f), scale_(1.0f) { model_ = new ModelRenderer(&missile); // Make sure the missile is not too large const float maxSize = 2.0f; Vector min = model_->getModel()->getMin(); Vector max = model_->getModel()->getMax(); float size = (max - min).Magnitude(); if (size > maxSize) innerScale_ = 2.2f / size; // Add lense flares (if any) std::vector::iterator itor; for (itor = model_->getModel()->getMeshes().begin(); itor != model_->getModel()->getMeshes().end(); itor++) { Mesh *mesh = (*itor); const char *name = mesh->getName(); if (strstr(name, "\"Flare") == name || strstr(name, "\"flare") == name) { FlareInfo info; // Find the center that the flare should be eminated from info.position = (mesh->getMax() + mesh->getMin()) / 2.0f; info.size = MAX(1.0f, (mesh->getMax() - mesh->getMin()).Magnitude()); flares_.push_back(info); } } } MissileMesh::~MissileMesh() { delete model_; } void MissileMesh::draw(Vector &position, Vector &direction, int flareType, float rotation) { // Figure out the opengl roation matrix from the direction // of the fired missile Vector dir = direction.Normalize(); const float radToDeg = 180.0f / 3.14f; float angXYRad = 3.14f - atan2f(dir[0], dir[1]); float angYZRad = acosf(dir[2]); float angXYDeg = angXYRad * radToDeg; float angYZDeg = angYZRad * radToDeg; // Apply the matrix and render the missile float scale = innerScale_ * scale_; glPushMatrix(); glTranslatef(position[0], position[1], position[2]); glRotatef(angXYDeg, 0.0f, 0.0f, 1.0f); glRotatef(angYZDeg, 1.0f, 0.0f, 0.0f); glRotatef(rotation, 0.0f, 0.0f, 1.0f); glScalef(scale, scale, scale); model_->draw(); glPopMatrix(); // Draw any lense flares associated with the missile std::list::iterator flareItor; for (flareItor = flares_.begin(); flareItor != flares_.end(); flareItor++) { FlareInfo info = (*flareItor); float newX = info.position[0]; float newY = (info.position[1] * getFastCos(angYZRad)) - (info.position[2] * getFastSin(angYZRad)); float newZ = (info.position[1] * getFastSin(angYZRad)) + (info.position[2] * getFastCos(angYZRad)); float newX2 = (newX * getFastCos(angXYRad)) - (newY * getFastSin(angXYRad)); float newY2 = (newX * getFastSin(angXYRad)) + (newY * getFastCos(angXYRad)); float newZ2 = newZ; Vector newPos; newPos[0] = position[0] + newX2 * scale; newPos[1] = position[1] + newY2 * scale; newPos[2] = position[2] + newZ2 * scale; GLLenseFlare::instance()->draw(newPos, false, flareType, info.size); } } void MissileMesh::setScale(float scale) { scale_=scale; }