[Racer-svn] SF.net SVN: racer:[274] trunk
Status: Alpha
Brought to you by:
jlegg
From: <jl...@us...> - 2010-03-26 02:03:34
|
Revision: 274 http://racer.svn.sourceforge.net/racer/?rev=274&view=rev Author: jlegg Date: 2010-03-26 02:03:27 +0000 (Fri, 26 Mar 2010) Log Message: ----------- Allow boosters to be moved along an edge in the editor. Store booster's vertical position from the track too. Show boosters textured in the editor. Make Track::NearTrack more generic, it will stick to any navigation graph now. Modified Paths: -------------- trunk/libtrack/NearTrack.cpp trunk/libtrack/NearTrack.h trunk/libtrack/TrackAttachment.cpp trunk/libtrack/TrackAttachment.h trunk/libtrack/document/ChangeEdgeSegmentDelta.h trunk/libtrack/document/InsertTrackAttachmentDelta.cpp trunk/libtrack/document/Makefile.am trunk/libtrack/edit_base/Makefile.am trunk/libtrack/path/PathEdge.cpp trunk/libtrack/path/PathEdge.h trunk/libtrack/path/PathVertex.cpp trunk/libtrack/path/PathVertex.h trunk/racer/Engine/GameObjects/Car.cpp Added Paths: ----------- trunk/libtrack/document/MoveTrackAttachmentDelta.cpp trunk/libtrack/document/MoveTrackAttachmentDelta.h trunk/libtrack/edit_base/TrackAttachmentHandle.cpp trunk/libtrack/edit_base/TrackAttachmentHandle.h Modified: trunk/libtrack/NearTrack.cpp =================================================================== --- trunk/libtrack/NearTrack.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/NearTrack.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -16,8 +16,8 @@ namespace Track { -NearTrack::NearTrack(const Track & track, btVector3 position) - : m_track(track) +NearTrack::NearTrack(const MeshFaces::Graph & graph, btVector3 position) + : m_graph(graph) { jump_to(position); } @@ -58,8 +58,7 @@ // again. // Stop when the nearest point is not on an edge, or is father away than // a point already considered. - const MeshFaces::Graph & graph(m_track.get_ai_graph()); - MeshFaces::FaceGraph face = graph[m_face]; + MeshFaces::FaceGraph face = m_graph[m_face]; m_world_coord = face.find_nearest_point(position); btVector3 face_coord = face.to_face_coords(m_world_coord); btScalar this_distance = position.distance2(m_world_coord); @@ -83,10 +82,9 @@ btVector3 best_world_coord = m_world_coord; // Find connected faces. - MeshFaces::Graph::vertex_descriptor best_face = m_face; typedef MeshFaces::Graph::adjacency_iterator AdjacencyIterator; std::pair<AdjacencyIterator, AdjacencyIterator> its; - for (its = boost::adjacent_vertices(m_face, graph); + for (its = boost::adjacent_vertices(m_face, m_graph); its.first != its.second; its.first++) { @@ -116,15 +114,14 @@ btScalar NearTrack::jump_to(btVector3 position) { // find the nearest point on the mesh to the given position. - const MeshFaces::Graph & graph(m_track.get_ai_graph()); btScalar max_distance2 = std::numeric_limits<btScalar>::max(); std::pair<MeshFaces::Graph::vertex_iterator, MeshFaces::Graph::vertex_iterator> vits; - for (vits = boost::vertices(graph); + for (vits = boost::vertices(m_graph); vits.first != vits.second; vits.first++) { MeshFaces::Graph::vertex_descriptor v_descriptor = *(vits.first); - MeshFaces::FaceGraph face = graph[v_descriptor]; + MeshFaces::FaceGraph face = m_graph[v_descriptor]; // Find the nearest point to plane on this triangle btVector3 nearest_point = face.find_nearest_point(position); btScalar distance2 = nearest_point.distance2(position); @@ -139,6 +136,7 @@ } // find other information about the attachment point. set_info(); + return max_distance2; } btVector3 NearTrack::get_position() const @@ -163,8 +161,7 @@ void NearTrack::set_info() { - const MeshFaces::Graph & graph(m_track.get_ai_graph()); - MeshFaces::FaceGraph face = graph[m_face]; + MeshFaces::FaceGraph face = m_graph[m_face]; /** @todo Set m_object_coord correctly. * It would make it easier to move correctly when the object it is * attached to is moved. Modified: trunk/libtrack/NearTrack.h =================================================================== --- trunk/libtrack/NearTrack.h 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/NearTrack.h 2010-03-26 02:03:27 UTC (rev 274) @@ -12,23 +12,27 @@ #ifndef LIBTRACK_NEAR_TRACK_H #define LIBTRACK_NEAR_TRACK_H -#include "Track.h" +#include "Mesh/MeshFaces.h" + #include <set> namespace Track { +class Track; + /** An object which has an attachment point to an AI mesh. */ class NearTrack { public: - /** Make an object positioned on a track. - * @param track The track to constrain too. Cannot be changed. + /** Construct with an initial position. + * @param graph The navigation grap to constrain too. Cannot be + * changed or deleted until the NearTrack is deleted. * @param position The nearest world space coordinates to the desired * starting position. */ - NearTrack(const Track & track, btVector3 position); + NearTrack(const MeshFaces::Graph & graph, btVector3 position); virtual ~NearTrack(); @@ -120,8 +124,8 @@ */ btScalar m_face_t; - /// Reference to the track which the object is in. - const Track & m_track; + /// The mesh we can navigate over. + const MeshFaces::Graph & m_graph; /// The vertices examined in move_towards(). std::set<MeshFaces::Graph::vertex_descriptor> examined; Modified: trunk/libtrack/TrackAttachment.cpp =================================================================== --- trunk/libtrack/TrackAttachment.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/TrackAttachment.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -2,7 +2,7 @@ * @brief Implement the Track::TrackAttachment class. * @author James Legg */ -/* Copyright © 2009 James Legg. +/* Copyright © 2009, 2010 James Legg. 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 @@ -20,22 +20,30 @@ return std::string ("Track::TrackAttachment");; } -const unsigned int latest_track_attachment_file_version = 1; +const unsigned int latest_track_attachment_file_version = 2; TrackAttachment::TrackAttachment(std::istream & source) { unsigned int version; source >> version; - if (version < latest_track_attachment_file_version) + if (version == 1) { + m_vertical_position = 0; + } + else if (version < latest_track_attachment_file_version) + { throw DepreciatedVersionError(); } - if (version > latest_track_attachment_file_version) + else if (version > latest_track_attachment_file_version) { throw NewVersionError(); } source >> m_t_position; source >> m_lateral_position; + if (version > 1) + { + source >> m_vertical_position; + } } TrackAttachment::TrackAttachment() @@ -68,11 +76,22 @@ m_lateral_position = value; } +btScalar TrackAttachment::get_vertical_position() const +{ + return m_vertical_position; +} + +void TrackAttachment::set_vertical_position(btScalar value) +{ + m_vertical_position = value; +} + void TrackAttachment::add_data(std::ostream & destination) const { destination << latest_track_attachment_file_version << " " << m_t_position << " " - << m_lateral_position; + << m_lateral_position << " " + << m_vertical_position; } void TrackAttachment::draw() const Modified: trunk/libtrack/TrackAttachment.h =================================================================== --- trunk/libtrack/TrackAttachment.h 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/TrackAttachment.h 2010-03-26 02:03:27 UTC (rev 274) @@ -2,7 +2,7 @@ * @brief Declare the Track::TrackAttachment class. * @author James Legg */ -/* Copyright © 2009 James Legg. +/* Copyright © 2009, 2010 James Legg. 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 @@ -15,11 +15,15 @@ #include <LinearMath/btScalar.h> #include "UniqueIdentifier.h" #include "ClassLoader.h" +#include "NearTrack.h" namespace Track { -/** Any object that is attached to a path. +/** An object in a Track that is locked to the Path. + * It is fixed onto an edge or vertex in the track editor. When the edge or + * vertex is moved, it remains fixed to the same point in the track. + * It attaches to the surface of the AI navigation mesh. */ class TrackAttachment : public UniqueIdentifier @@ -38,6 +42,12 @@ /// Set the position along the track perpendicular to the edge's direction. void set_lateral_position(btScalar value); + btScalar get_vertical_position() const; + /** Set the position in the direction of the track's normal. + * This is for the z direction in car space. + */ + void set_vertical_position(btScalar value); + /** Write the data needed to reconstruct the object to a stream. */ virtual void add_data(std::ostream & stream) const; @@ -60,6 +70,11 @@ * 0 is on the curve itself. */ btScalar m_lateral_position; + /** Offset from the centre perpendicular to the track in spacial units. + * Positive is above the track in the normal direction travel. + * 0 is on the curve itself. + */ + btScalar m_vertical_position; }; // Add a TrackAttachment or its children to a stream. Modified: trunk/libtrack/document/ChangeEdgeSegmentDelta.h =================================================================== --- trunk/libtrack/document/ChangeEdgeSegmentDelta.h 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/document/ChangeEdgeSegmentDelta.h 2010-03-26 02:03:27 UTC (rev 274) @@ -2,7 +2,7 @@ * @brief Declare the Document::ChangeEdgeSegmentDelta class. * @author James Legg */ -/* Copyright © 2009 James Legg. +/* Copyright © 2009, 2010 James Legg. 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 @@ -15,7 +15,6 @@ #include <cstddef> #include "ChangePropertyDelta.h" -#include "../path/Path.h" namespace Document { Modified: trunk/libtrack/document/InsertTrackAttachmentDelta.cpp =================================================================== --- trunk/libtrack/document/InsertTrackAttachmentDelta.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/document/InsertTrackAttachmentDelta.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -5,7 +5,7 @@ * Document::RemoveTrackAttachmentDelta classes. * @author James Legg */ -/* Copyright © 2009 James Legg. +/* Copyright © 2009, 2010 James Legg. 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 @@ -36,22 +36,23 @@ // insert. // First check if we are adding the right object. assert((object->get_name() == identifier.first)); - track.get_path().get_edge(identifier.second).attachments.push_back(object); + track.get_path().get_edge(identifier.second).insert_attachment(object); } boost::shared_ptr<Track::TrackAttachment> InsertRemoveTrackAttachmentIdentifier::remove(Track::Track & track) const { // remove but return a copy. typedef std::vector<boost::shared_ptr<Track::TrackAttachment> > VectorType; - VectorType & vector = track.get_path().get_edge(identifier.second).attachments; - for (VectorType::iterator it = vector.begin(); + Track::PathEdge & edge = track.get_path().get_edge(identifier.second); + const VectorType & vector = edge.get_attachments(); + for (VectorType::const_iterator it = vector.begin(); it != vector.end(); it++) { if ((**it).get_name() == identifier.first) { boost::shared_ptr<Track::TrackAttachment> ptr = (*it); - vector.erase(it); + edge.remove_attachment(identifier.first); return ptr; } } Modified: trunk/libtrack/document/Makefile.am =================================================================== --- trunk/libtrack/document/Makefile.am 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/document/Makefile.am 2010-03-26 02:03:27 UTC (rev 274) @@ -1,4 +1,23 @@ noinst_LTLIBRARIES = libdocument.la -libdocument_la_SOURCES = ChangeEdgeSegmentDelta.cpp ChangeEdgeSegmentDelta.h ChangePropertyDelta.h ChangeVertexSegmentDelta.cpp ChangeVertexSegmentDelta.h ClearVertexDelta.h ClearVertexDelta.cpp Document.cpp Document.h DocumentDelta.cpp DocumentDelta.h FlipEdgeDelta.cpp FlipEdgeDelta.h InsertDelta.h InsertEdgeDelta.cpp InsertEdgeDelta.h InsertRemoveIdentifier.h InsertTrackAttachmentDelta.cpp InsertTrackAttachmentDelta.h InsertVertexDelta.cpp InsertVertexDelta.h MoveNodeDelta.cpp MoveNodeDelta.h RemoveDelta.h RotateVertexDelta.h RotateVertexDelta.cpp SetEdgeStrengthDelta.cpp SetEdgeStrengthDelta.h SetStartEdgeDelta.cpp SetStartEdgeDelta.h StackableDelta.cpp StackableDelta.h SymmetricDelta.cpp SymmetricDelta.h +libdocument_la_SOURCES = ChangeEdgeSegmentDelta.cpp ChangeEdgeSegmentDelta.h\ + ChangePropertyDelta.h\ + ChangeVertexSegmentDelta.cpp ChangeVertexSegmentDelta.h\ + ClearVertexDelta.h ClearVertexDelta.cpp\ + Document.cpp Document.h\ + DocumentDelta.cpp DocumentDelta.h\ + FlipEdgeDelta.cpp FlipEdgeDelta.h\ + InsertDelta.h\ + InsertEdgeDelta.cpp InsertEdgeDelta.h\ + InsertRemoveIdentifier.h\ + InsertTrackAttachmentDelta.cpp InsertTrackAttachmentDelta.h\ + InsertVertexDelta.cpp InsertVertexDelta.h\ + MoveNodeDelta.cpp MoveNodeDelta.h\ + MoveTrackAttachmentDelta.cpp MoveTrackAttachmentDelta.h\ + RemoveDelta.h\ + RotateVertexDelta.h RotateVertexDelta.cpp\ + SetEdgeStrengthDelta.cpp SetEdgeStrengthDelta.h\ + SetStartEdgeDelta.cpp SetStartEdgeDelta.h\ + StackableDelta.cpp StackableDelta.h\ + SymmetricDelta.cpp SymmetricDelta.h libdocument_la_CPPFLAGS = $(debug_specific_CFLAGS) $(libtrack_CFLAGS) -I@top_srcdir@ Added: trunk/libtrack/document/MoveTrackAttachmentDelta.cpp =================================================================== --- trunk/libtrack/document/MoveTrackAttachmentDelta.cpp (rev 0) +++ trunk/libtrack/document/MoveTrackAttachmentDelta.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -0,0 +1,48 @@ +/** @file document/MoveTrackAttachmentDelta.cpp + * @brief Implement the Document::TrackAttachmentPositionFinder and Document::MoveNodeDelta classes. + * @author James Legg + */ +/* Copyright © 2010 James Legg. + 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. +*/ + +#include "MoveTrackAttachment.h" +#include <vector> +#include <boost/shared_ptr.hpp> +#include "../Track.h" + +namespace Document +{ + +TrackAttachmentPositionFinder::TrackAttachmentPositionFinder( + std::size_t edge_name, std::size_t attachment_name) + : m_edge_name(edge_name) + , m_attachment_name(attachment_name) +{ +} + +void TrackAttachmentPositionFinder::read(const Track::Track & track, + btVector3 & position) +{ + const Track::PathEdge & edge(track.get_path().get_edge(m_edge_name)); + const Track::TrackAttachment & attachment = edge.get_attachment(m_attachment_name); + position = btVector3(attachment.get_t_position(), + attachment.get_lateral_position(), + attachment.get_vertical_position()); +} + +void TrackAttachmentPositionFinder::write(Track::Track & track, + const btVector3 & new_position) +{ + Track::PathEdge & edge (track.get_path().get_edge(m_edge_name)); + Track::TrackAttachment attachment = edge.get_attachment(m_attachment_name); + attachment.set_t_position(new_position.x()); + attachment.set_lateral_position(new_position.y()); + attachment.set_vertical_position(new_position.z()); + edge.set_attachment(m_attachment_name, attachment); +} + +} // namespace Document Added: trunk/libtrack/document/MoveTrackAttachmentDelta.h =================================================================== --- trunk/libtrack/document/MoveTrackAttachmentDelta.h (rev 0) +++ trunk/libtrack/document/MoveTrackAttachmentDelta.h 2010-03-26 02:03:27 UTC (rev 274) @@ -0,0 +1,61 @@ +/** @file document/MoveTrackAttachmentDelta.h + * @brief Declare the Document::MoveTrackAttachmentDelta and Document::TrackAttachmentPositionFinderclass. + * @author James Legg + */ +/* Copyright © 2010 James Legg. + 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. +*/ + +#ifndef DOCUMENT_MOVE_TRACK_ATTACHMENT_DELTA_H +#define DOCUMENT_MOVE_TRACK_ATTACHMENT_DELTA_H + +#include "ChangePropertyDelta.h" + +#include <LinearMath/btVector3.h> + +namespace Document +{ + +/** Find or set the position of a vertex. + */ +class TrackAttachmentPositionFinder + : public PropertyDeltaIdentifier<btVector3> +{ + public: + /** Create, associating with a vertex. + * @param edge_name The name of the edge with the attachment on it. + * @param attachment_nmae The name of the attachment. + */ + TrackAttachmentPositionFinder(std::size_t edge_name, std::size_t attachment_name); + + /** Get the location of the associated track attachment. + * @param track The Track the associated vertex is in. + * @param position Position of the TrackAttachment. The first + * component is how far along the edge's curve the point is on the + * scale of 0 (beginning) to 1 (end). The second component is the + * lateral position, and the third component is the vertical position. + */ + virtual void read(const Track::Track & track, btVector3 & position); + + /** Move the associated track attachment. + * @param track The Track containing the associated vertex. + * @param new_position The location to move the associated vertex to. + */ + virtual void write(Track::Track & track, const btVector3 & new_position); + protected: + /// The name of the edge. + std::size_t m_edge_name; + /// The name of the attachment + std::size_t m_attachment_name; +}; + +/** Command for moving control points along the path. +*/ +typedef ChangePropertyDelta<TrackAttachmentPositionFinder, btVector3> MoveTrackAttachmentDelta; + +} // namespace Document + +#endif // DOCUMENT_MOVE_TRACK_ATTACHMENT_DELTA_H Modified: trunk/libtrack/edit_base/Makefile.am =================================================================== --- trunk/libtrack/edit_base/Makefile.am 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/edit_base/Makefile.am 2010-03-26 02:03:27 UTC (rev 274) @@ -1,3 +1,11 @@ noinst_LTLIBRARIES = libedit_base.la -libedit_base_la_SOURCES = ControlPoint.cpp ControlPoint.h Dragable.cpp Dragable.h EdgeStrengthHandle.cpp EdgeStrengthHandle.h LineConstrainedControlPoint.cpp LineConstrainedControlPoint.h RotationHandle.cpp RotationHandle.h SegmentConnectionHandle.cpp SegmentConnectionHandle.h Selectable.h VertexRotationHandle.cpp VertexRotationHandle.h +libedit_base_la_SOURCES = ControlPoint.cpp ControlPoint.h\ + Dragable.cpp Dragable.h\ + EdgeStrengthHandle.cpp EdgeStrengthHandle.h\ + LineConstrainedControlPoint.cpp LineConstrainedControlPoint.h\ + RotationHandle.cpp RotationHandle.h\ + SegmentConnectionHandle.cpp SegmentConnectionHandle.h\ + Selectable.h\ + TrackAttachmentHandle.cpp TrackAttachmentHandle.h\ + VertexRotationHandle.cpp VertexRotationHandle.h libedit_base_la_CPPFLAGS = $(debug_specific_CFLAGS) $(libtrack_CFLAGS) -I@top_srcdir@ Added: trunk/libtrack/edit_base/TrackAttachmentHandle.cpp =================================================================== --- trunk/libtrack/edit_base/TrackAttachmentHandle.cpp (rev 0) +++ trunk/libtrack/edit_base/TrackAttachmentHandle.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -0,0 +1,64 @@ +/** @file libtrack/edit_base/TrackAttachmentHandle.cpp + * @brief Implement the Track::EditAssist::TrackAttachmentHandle class. + * @author James Legg + */ +/* Copyright © 2010 James Legg. + 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. +*/ + +#include "TrackAttachmentHandle.h" +#include "../document/MoveTrackAttachmentDelta.h" +#include "../path/PathEdge.h" + +namespace Track +{ + +namespace EditAssist +{ + +TrackAttachmentHandle::TrackAttachmentHandle(const PathEdge & edge, std::size_t attachment_index) + : m_edge(edge) + , m_attachment_index(attachment_index) +{ +} + +void TrackAttachmentHandle::draw() const +{ + // Will probably be covered by the attachment in most views, + // but is useful from some angles. + glColor3f(0.0, 1.0, 1.0); + glBegin(GL_POINTS); + glVertex3f(position.x(), position.y(), position.z()); + glEnd(); +} + +void TrackAttachmentHandle::snap(btVector3 & position, btVector3 normal) const +{ + btScalar s = m_edge.get_nearest_s(position, position + normal); + position = m_edge.get_transform(s).getOrigin(); +} + +boost::shared_ptr<Document::DocumentDelta> TrackAttachmentHandle::make_delta(btVector3 position) const +{ + // position should have been snapped with snap, + // so it doesn't really matter that we do not know the direction. + // but the line should have non-zero length for the maths to work. + btScalar s = m_edge.get_nearest_s(position, position + btVector3(0.001, 0.001, 0.001)); + + TrackAttachment & attachment = *(m_edge.get_attachments()[m_attachment_index]); + btVector3 new_pos(s, attachment.get_lateral_position(), + attachment.get_vertical_position()); + + return boost::shared_ptr<Document::DocumentDelta>(new + Document::MoveTrackAttachmentDelta( + Document::TrackAttachmentPositionFinder(m_edge.get_name(), + attachment.get_name()), + new_pos)); +} + +} // namespace EditAssist + +} // namespace Track Added: trunk/libtrack/edit_base/TrackAttachmentHandle.h =================================================================== --- trunk/libtrack/edit_base/TrackAttachmentHandle.h (rev 0) +++ trunk/libtrack/edit_base/TrackAttachmentHandle.h 2010-03-26 02:03:27 UTC (rev 274) @@ -0,0 +1,45 @@ +/** @file libtrack/edit_base/TrackAttachmentHandle.h + * @brief Declare the Track::EditAssist::TrackAttachmentHandle class. + * @author James Legg + */ +/* Copyright © 2010 James Legg. + 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. +*/ +#ifndef LIBTRACK_EDIT_BASE_TRACK_ATTACHMENT_HANDLE_H +#define LIBTRACK_EDIT_BASE_TRACK_ATTACHMENT_HANDLE_H + +#include "ControlPoint.h" + +namespace Track +{ + +class PathEdge; + +namespace EditAssist +{ + +/** Control point for an object which can be dragged along an edge. + */ +class TrackAttachmentHandle + : public ControlPoint +{ +public: + TrackAttachmentHandle(const PathEdge & edge, std::size_t attachment_index); + virtual void draw() const; + + virtual void snap(btVector3 & position, btVector3 normal) const; + + virtual boost::shared_ptr<Document::DocumentDelta> make_delta(btVector3 position) const; +protected: + const PathEdge & m_edge; + std::size_t m_attachment_index; +}; + +} + +} + +#endif // LIBTRACK_EDIT_BASE_TRACK_ATTACHMENT_HANDLE_H Modified: trunk/libtrack/path/PathEdge.cpp =================================================================== --- trunk/libtrack/path/PathEdge.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/path/PathEdge.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -44,10 +44,10 @@ if (file_version > path_edge_newest_version) throw NewVersionError(); if (file_version >= 2) { - SaveableClassList::get_instance()->fill_vector(source, attachments); + SaveableClassList::get_instance()->fill_vector(source, m_attachments); // Link all the attachments to this edge so they can be safely added and removed. - for (std::vector<boost::shared_ptr<TrackAttachment> >::iterator it = attachments.begin(); - it != attachments.end(); + for (std::vector<boost::shared_ptr<TrackAttachment> >::iterator it = m_attachments.begin(); + it != m_attachments.end(); it++) { (**it).edge_name = get_name(); @@ -143,10 +143,24 @@ // update control point handles. start.handle.update(p0, source_in.get_angle(start_index), start.gradient_strength); finish.handle.update(p3, target_in.get_angle(finish_index), finish.gradient_strength); + recreate_attachment_handles(); bounds |= graphics_bounds; bounds |= start.handle.get_position(); bounds |= finish.handle.get_position(); + + // Navigation mesh + m_nav_mesh = MeshFaces(); + for (unsigned int i = 0; i < number_of_repetions; i++) + { + PieceDistortion transform(*this, i, + segment->get_length(), + segment->get_minimum_y()); + m_nav_mesh |= segment->get_ai_mesh().get_distorted_faces(transform); + } + m_nav_mesh.merge_doubles(); + m_nav_mesh.set_source(true, get_name()); + m_navigation_graph = m_nav_mesh.get_connectivity(); } btScalar PathEdge::get_length() const @@ -255,6 +269,56 @@ return false; } +float PathEdge::get_nearest_s(btVector3 start, btVector3 stop) const +{ + /* We should find the smallest distance between the line segment between + * start and stop and the cubic bezier spline of the edge. + * Instead, we'll find an approximation by using a piecewise linear + * approximation of the cubic bezier. + */ + /** @todo should share more code with is_here. + * Calculate positions in update? + */ + btVector3 length = stop - start; + btVector3 e2, e1; + ///@todo we only need the position, not the full transformation. + e2 = get_transform(0).getOrigin(); + const btScalar step = one_over_two_to_the_power_of<4>::result; + btScalar min_distance = std::numeric_limits<btScalar>::max(); + btScalar best_result; + for (btScalar t = step; t < 1.0; t += step) + { + e1 = e2; + e2 = get_transform(t).getOrigin(); + // now e1->e2 is the line segment we will test. + btVector3 ed = e2 - e1; + btVector3 w = start - e1; + btScalar a = length.dot(length); + btScalar b = length.dot(ed); + btScalar c = ed.dot(ed); + btScalar d = length.dot(w); + btScalar e = ed.dot(w); + btScalar denominator = a * c - b * b; + btScalar screen = b * e - c * d; + btScalar section = a * e - b * d; + // Now check if this is along the segments. + if (screen < 0) screen = 0; + if (screen > denominator) screen = denominator; + if (section < 0) section = 0; + if (section > denominator) section = denominator; + // find distance + btScalar distance = (w + (screen * length - section * ed) / denominator).length2(); + if (distance < min_distance) + { + min_distance = distance; + best_result = t + (section / denominator - 1) * step; + } + } + if (best_result < 0.0) return 0; + else if (best_result > 1.0) return 1.0; + else return best_result; +} + const EditAssist::ControlPoint * PathEdge::get_control_point_here(btVector3 start_pos, btVector3 stop_pos, btScalar radius) const { if (start.handle.is_here(start_pos, stop_pos, radius)) @@ -265,6 +329,19 @@ { return &(finish.handle); } + else + { + for (std::vector<boost::shared_ptr<EditAssist::TrackAttachmentHandle> >::const_iterator + it = m_attachment_handles.begin(); + it != m_attachment_handles.end(); + it++) + { + if ((**it).is_here(start_pos, stop_pos, radius)) + { + return &(**(it)); + } + } + } // can't find a near enough control point. return 0; } @@ -310,15 +387,7 @@ void PathEdge::add_ai_faces(MeshFaces & mesh) const { - for (unsigned int i = 0; i < number_of_repetions; i++) - { - PieceDistortion transform(*this, i, - segment->get_length(), - segment->get_minimum_y()); - MeshFaces faces = segment->get_ai_mesh().get_distorted_faces(transform); - faces.set_source(true, get_name()); - mesh |= faces; - } + mesh |= m_nav_mesh; } AxisAlignedBoundingBox PathEdge::get_bounds() const @@ -371,22 +440,33 @@ void PathEdge::draw_attachments() const { // Draw attachments. - for (std::vector<boost::shared_ptr<TrackAttachment> >::const_iterator it = attachments.begin(); - it != attachments.end(); + if (render_mode == DrawableMesh::RM_WIREFRAME) + { + glEnable(GL_TEXTURE_2D); + } + for (std::vector<boost::shared_ptr<TrackAttachment> >::const_iterator it = m_attachments.begin(); + it != m_attachments.end(); it++) { glPushMatrix(); + /// @todo claculate the matrix beforehand, then use that. btTransform transform = get_transform((**it).get_t_position()); + transform.setOrigin(transform(btVector3((**it).get_lateral_position(), + 0.0, + (**it).get_vertical_position()))); btScalar mat[16]; mat[15] = 1.0; transform.getOpenGLMatrix(mat); glMultMatrixf(mat); // Something funny is going on with the matrix multiplication :-/ glScalef(1.0, -1.0, 1.0); - glTranslatef((**it).get_lateral_position(), 0.0, 0.0); (**it).draw(); glPopMatrix(); } + if (render_mode == DrawableMesh::RM_WIREFRAME) + { + glDisable(GL_TEXTURE_2D); + } } void PathEdge::make_cache() const @@ -398,6 +478,85 @@ } } +void PathEdge::insert_attachment(boost::shared_ptr<TrackAttachment> attachment) +{ + m_attachments.push_back(attachment); + recreate_attachment_handles(); +} + +void PathEdge::remove_attachment(std::size_t attachment_name) +{ + std::vector<boost::shared_ptr<TrackAttachment> >::iterator attach_it; + for (attach_it = m_attachments.begin(); + (**attach_it).get_name() != attachment_name; + attach_it++) + { + assert(attach_it != m_attachments.end()); + } + assert(attach_it != m_attachments.end()); + m_attachments.erase(attach_it); + // the attachment handles need to know their new index. Recreate them. + recreate_attachment_handles(); +} + +const TrackAttachment & PathEdge::get_attachment(std::size_t attachment_name) const +{ + std::vector<boost::shared_ptr<TrackAttachment> >::const_iterator attach_it; + for (attach_it = m_attachments.begin(); + (**attach_it).get_name() != attachment_name; + attach_it++) + { + assert(attach_it != m_attachments.end()); + } + assert(attach_it != m_attachments.end()); + return **attach_it; +} + +void PathEdge::set_attachment(std::size_t attachment_name, + const TrackAttachment & attachment) +{ + std::vector<boost::shared_ptr<TrackAttachment> >::iterator attach_it; + unsigned int index = 0; + for (attach_it = m_attachments.begin(); + (**attach_it).get_name() != attachment_name; + attach_it++, index++) + { + assert(attach_it != m_attachments.end()); + } + assert(attach_it != m_attachments.end()); + (**attach_it) = attachment; + // Set correct handle position. + btTransform transform = get_transform(attachment.get_t_position()); + m_attachment_handles[index]->set_position( + transform(btVector3(attachment.get_lateral_position(), + 0.0, + attachment.get_vertical_position()))); + +} + +void PathEdge::recreate_attachment_handles() +{ + m_attachment_handles.clear(); + for (std::size_t i = 0; i < m_attachments.size(); i++) + { + m_attachment_handles.push_back( + boost::shared_ptr<EditAssist::TrackAttachmentHandle>( + new EditAssist::TrackAttachmentHandle(*this, i))); + EditAssist::TrackAttachmentHandle & handle = *(m_attachment_handles.back()); + const TrackAttachment & attachment = *(m_attachments[i]); + + btTransform transform = get_transform(attachment.get_t_position()); + handle.set_position(transform(btVector3(attachment.get_lateral_position(), + 0.0, + attachment.get_vertical_position()))); + } +} + +const std::vector<boost::shared_ptr<TrackAttachment> > & PathEdge::get_attachments() const +{ + return m_attachments; +} + std::ostream & operator<<(std::ostream & destination, const PathEdge & path_edge) { destination << path_edge_newest_version << ' '; @@ -405,7 +564,7 @@ destination << ' ' << path_edge.start << ' ' << path_edge.finish << ' '; - SaveableClassList::get_instance()->write_vector(destination, path_edge.attachments); + SaveableClassList::get_instance()->write_vector(destination, path_edge.get_attachments()); return destination; } Modified: trunk/libtrack/path/PathEdge.h =================================================================== --- trunk/libtrack/path/PathEdge.h 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/path/PathEdge.h 2010-03-26 02:03:27 UTC (rev 274) @@ -32,6 +32,7 @@ #include "../AxisAlignedBoundingBox.h" #include "../AABBDrawable.h" #include "../TrackAttachment.h" +#include "../edit_base/TrackAttachmentHandle.h" namespace Track { @@ -79,7 +80,8 @@ * You should call this after changing any related geometry: the vertices at * the ends of the arc, the gradient in the PathEdgeEnds, or the Segment * that runs along the arc. - * After this has been called, the length, repetitions, and mesh will be + * After this has been called, the length, repetitions, and nav mesh, and + * graphical meshes will be * up to date. * The objects referenced by the parameters must not be freed when this * object is still being used, unless this function is called again. @@ -138,6 +140,14 @@ virtual bool is_here(btVector3 start, btVector3 stop, btScalar radius) const; + /** Get the nearest point along the curve to a line segment. + * @param start one end of the line segment. + * @param stop the other end of the line segment. + * @return scalar s between 0 and 1 such that get_transform(s).origin() is + * the closest to the line segment for any value of s between 0 and 1. + */ + btScalar get_nearest_s(btVector3 start, btVector3 stop) const; + /** Find a control point under a mouse cursor. * @return 0 if none near control point, otherwise an apropriate edge * handle. @@ -180,8 +190,31 @@ void draw_attachments() const; /// Load meshes into graphics memory. void make_cache() const; - std::vector<boost::shared_ptr<TrackAttachment> > attachments; + + /** Put an attachment on the edge. + * Precondition: Attachment removed. + * Postcondition: Attachment added. + */ + void insert_attachment(boost::shared_ptr<TrackAttachment> attachment); + /** Remove an attachment from the edge. + * Precondition: aattachment added with given name. + * Postcondition: attachment removed. + */ + void remove_attachment(std::size_t attachment_name); + /** Get a list of attachments on the edge. + */ + const std::vector<boost::shared_ptr<TrackAttachment> > & get_attachments() const; + /** Get an attachment on the edge by name. + * Precondition: attachment added with given name. + */ + const TrackAttachment & get_attachment(std::size_t attachment_name) const; + /** Modify an attachment on the edge by name. + * Precondition: attachment added with given name. + */ + void set_attachment(std::size_t attachment_name, const TrackAttachment & attachment); protected: + std::vector<boost::shared_ptr<TrackAttachment> > m_attachments; + std::vector<boost::shared_ptr<EditAssist::TrackAttachmentHandle> > m_attachment_handles; btScalar length; unsigned int number_of_repetions; std::vector<boost::shared_ptr<DrawableMesh> > meshes; @@ -192,6 +225,11 @@ AxisAlignedBoundingBox bounds; /// The minimal axis aligned bounding box of the edge's graphical meshes. AxisAlignedBoundingBox graphics_bounds; + /// The navigation mesh + MeshFaces m_nav_mesh; + MeshFaces::Graph m_navigation_graph; + + void recreate_attachment_handles(); }; std::ostream & operator<<(std::ostream & destination, Modified: trunk/libtrack/path/PathVertex.cpp =================================================================== --- trunk/libtrack/path/PathVertex.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/path/PathVertex.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -298,6 +298,9 @@ if(segment) { m_bounds = segment->get_graphics_mesh().get_faces().get_bounds().transform(m_transform); + m_nav_mesh = segment->get_ai_mesh().get_distorted_faces(m_transform); + m_nav_mesh.set_source(false, get_name()); + m_navigation_graph = m_nav_mesh.get_connectivity(); } } Modified: trunk/libtrack/path/PathVertex.h =================================================================== --- trunk/libtrack/path/PathVertex.h 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/libtrack/path/PathVertex.h 2010-03-26 02:03:27 UTC (rev 274) @@ -2,7 +2,7 @@ * @brief Declare the Track::PathVertex class. * @author James Legg */ -/* Copyright © 2009 James Legg. +/* Copyright © 2009, 2010 James Legg. 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 @@ -187,7 +187,13 @@ /// The transformation of the segment to world space. btTransform m_transform; - /// Set the correct value for m_bounds and m_transform. + /// The navigation mesh. + MeshFaces m_nav_mesh; + MeshFaces::Graph m_navigation_graph; + + /** Set the correct value for m_bounds and m_transform and update the + * navigation graph. + */ void calculate_bounds(); /// Update the properties of the vertices control points. Modified: trunk/racer/Engine/GameObjects/Car.cpp =================================================================== --- trunk/racer/Engine/GameObjects/Car.cpp 2010-03-14 14:20:21 UTC (rev 273) +++ trunk/racer/Engine/GameObjects/Car.cpp 2010-03-26 02:03:27 UTC (rev 274) @@ -90,7 +90,7 @@ Car::Car(Physics::World & world, btTransform start, InputDevice * input_device, unsigned int car_model, const btVector3 & plane_normal, const btScalar & plane_distance, const btVector3 & start_point) - : NearTrack(world.get_track(), start.getOrigin()) + : NearTrack(world.get_track().get_ai_graph(), start.getOrigin()) , world(world), input_device(input_device), force(0, 0, 0), @@ -227,7 +227,7 @@ glEnd(); glBegin(GL_LINES); glColor3f(0,1,0); - const Track::MeshFaces::Graph & graph = m_track.get_ai_graph(); + const Track::MeshFaces::Graph & graph = world.get_track().get_ai_graph(); const btVector3 *v = graph[get_face_descriptor()].vertex_positions; glVertex3f(v[0].x(), v[0].y(), v[0].z()); glVertex3f(v[1].x(), v[1].y(), v[1].z()); @@ -339,9 +339,11 @@ edge_range.first++) { const Track::PathEdge & edge = path.graph[*(edge_range.first)]; - for (std::vector<boost::shared_ptr<Track::TrackAttachment> >::const_iterator it = edge.attachments.begin(); - it != edge.attachments.end(); - it++) + typedef std::vector<boost::shared_ptr<Track::TrackAttachment> > Vector; + const Vector & attachments = edge.get_attachments(); + for (Vector::const_iterator it = attachments.begin(); + it != attachments.end(); + it++) { const Track::TrackBooster * booster = dynamic_cast<const Track::TrackBooster*>(&(**it)); if (booster) @@ -598,8 +600,7 @@ { return 0; } - const Track::MeshFaces::Graph & graph = m_track.get_ai_graph(); - const Track::MeshFaces::FaceGraph face = graph[get_face_descriptor()]; + const Track::MeshFaces::FaceGraph face = m_graph[get_face_descriptor()]; return face_u_interpolation(face, face.find_nearest_point(get_position())); } @@ -637,8 +638,7 @@ return 0; } else { // current position. - const Track::MeshFaces::Graph & graph = m_track.get_ai_graph(); - const Track::MeshFaces::FaceGraph & face = graph[get_face_descriptor()]; + const Track::MeshFaces::FaceGraph & face = m_graph[get_face_descriptor()]; btVector3 current_coords = get_position(); btScalar current_lap_position = face_u_interpolation(face, current_coords); @@ -659,7 +659,7 @@ // centre. return 0; } - const Track::MeshFaces::FaceGraph & face2 = graph[front.get_face_descriptor()]; + const Track::MeshFaces::FaceGraph & face2 = m_graph[front.get_face_descriptor()]; btScalar facing_lap_position = face_u_interpolation(face2, facing_coords); btScalar difference = (current_lap_position - facing_lap_position) * 4.0 * 255; if (difference <= 0) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |