/* * pathmanager.cpp - author: Keith Fulton * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * 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 (version 2 of the License) * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include "util/log.h" #include "pathmanager.h" #include "npcbehave.h" //////////////////////////////////////////////////////////////////////// void psPath::CalculateAtTime (float time) { spline.Calculate (time+0.1); GetInterpolatedPosition(heading); spline.Calculate (time); } void psPath::GetInterpolatedForward (csVector3& pos) { GetInterpolatedPosition(pos); pos = pos - heading; } //////////////////////////////////////////////////////////////////////// bool PathManager::Load(iDocumentNode *node) { csRef iter = node->GetNodes(); while ( iter->HasNext() ) { csRef node = iter->Next(); if ( node->GetType() != CS_NODE_ELEMENT ) continue; // This is a widget so read it's factory to create it. if ( strcmp( node->GetValue(), "path" ) == 0) { Spline *spline = new Spline; if (spline->Load(node)) { paths.Insert(spline); } else { delete spline; return false; } } } return true; } Spline *PathManager::Find(const char *name) { Spline key(name); Spline *found = paths.Find(&key); return found; } csPath *PathManager::CreatePath(const char *name,csVector3& offset,csVector3& startpt) { Spline key(name); Spline *found = paths.Find(&key); if (found) { csPath *path = new psPath( found->points.Length() ); csVector3 *v = new csVector3[found->points.Length()]; int i; for (i=0; ipoints.Length(); i++) { v[i] = found->points[i]->pos; } path->SetPositionVectors(v); for (i=0; ipoints.Length(); i++) { v[i] = found->points[i]->up; } path->SetUpVectors(v); delete [] v; float *f = new float[ found->points.Length() ]; for (i=0; ipoints.Length(); i++) { f[i] = found->points[i]->time_value; } path->SetTimes(f); delete [] f; return path; } return NULL; } bool Spline::Load(iDocumentNode *node) { name = node->GetAttributeValue("name"); if (name.Length() == 0) { Error1("Path does not have a name attribute specified.\n"); return false; } sector = node->GetAttributeValue("sector"); if (name.Length() == 0) { Error1("Path does not have a sector attribute specified.\n"); return false; } constant_vel = node->GetAttributeValueAsFloat("constant_vel"); csRef iter = node->GetNodes(); float time_so_far = 0; SplinePoint *last = NULL; while ( iter->HasNext() ) { csRef node = iter->Next(); if ( node->GetType() != CS_NODE_ELEMENT ) continue; // This is a widget so read it's factory to create it. if ( strcmp( node->GetValue(), "spline_pt" ) == 0) { SplinePoint *pt = new SplinePoint; pt->pos.x = node->GetAttributeValueAsFloat("x"); pt->pos.y = node->GetAttributeValueAsFloat("y"); pt->pos.z = node->GetAttributeValueAsFloat("z"); pt->up.x = node->GetAttributeValueAsFloat("up_x"); pt->up.y = node->GetAttributeValueAsFloat("up_y"); pt->up.z = node->GetAttributeValueAsFloat("up_z"); if (node->GetAttributeValue("anim")) pt->action = node->GetAttributeValue("anim"); else pt->action = "default"; if (constant_vel) { if (last) { float dist = (last->pos-pt->pos).Norm(); time_so_far += (dist/constant_vel); pt->time_value = time_so_far; } else { pt->time_value = 0; } last = pt; } else { pt->time_value = node->GetAttributeValueAsFloat("time"); } points.Push(pt); } } return true; }