Permalink
Browse files

added polyline path, fixed forgotten circular path files

  • Loading branch information...
1 parent 1b414d4 commit e26a926cd25557ae686ed548c1ce77d31add66f2 @eilara committed Mar 3, 2012
View
1 README
@@ -16,6 +16,7 @@ TODO
see any tween updates, peek and warn if SV nature changes?
* add set_duration
* template specialization on proxies not method overloading
+* face angle feature for path tweens
INSTALLATION
View
@@ -11,17 +11,25 @@ our $VERSION = '0.01';
require XSLoader;
XSLoader::load('SDLx::Betweener', $VERSION);
+# tween types
+
use constant { TWEEN_INT => 0, TWEEN_FLOAT => 1, TWEEN_PATH => 2 };
my @Tween_Lookup = qw(_tween_int _tween_float _tween_path);
+# proxy types
+
use constant { DIRECT_PROXY => 1, CALLBACK_PROXY => 2, METHOD_PROXY => 3 };
my %Proxy_Lookup = do { my $i = 1; map { $_ => $i++ } qw(ARRAY CODE HASH)};
+# path types
+
use constant { LINEAR_PATH => 0, CIRCULAR_PATH => 1 };
my %Path_Lookup = do { my $i = 0; map { $_ => $i++ } qw(
- linear circular
+ linear circular polyline
)};
+# ease types
+
my @Ease_Names = qw(
linear
p2_in p2_out p2_in_out
@@ -147,3 +155,10 @@ sub tween {
}
1;
+
+__END__
+
+path => [
+ {linear => {from=>[1,2], to=>[3,4]}}
+ {linear => {from=>[1,2], to=>[3,4]}}
+],
View
@@ -0,0 +1,18 @@
+
+#include "CircularPath.h"
+
+CircularPath::CircularPath
+ (Vector2i center, int radius, float from_angle, float to_angle) :
+ center(center),
+ radius(radius),
+ from_angle(from_angle),
+ to_angle(to_angle),
+ angle_delta(to_angle - from_angle) {}
+
+Vector2i CircularPath::solve(float t) {
+ float angle = from_angle + angle_delta * t;
+ Vector2f dir = { { cos(angle), sin(angle) } };
+ return center + dir * radius;
+}
+
+
View
@@ -0,0 +1,21 @@
+
+#ifndef CIRCULARPATH_H
+#define CIRCULARPATH_H
+
+#include "VectorTypes.h"
+#include "IPath.h"
+
+class CircularPath : public IPath {
+
+ public:
+ CircularPath(Vector2i center, int radius, float from_angle, float to_angle);
+ Vector2i solve(float t);
+ private:
+ Vector2i center;
+ int radius;
+ float from_angle, to_angle;
+ float angle_delta;
+
+};
+
+#endif
View
@@ -0,0 +1,48 @@
+
+#include <algorithm>
+#include "PolylinePath.h"
+
+PolylinePath::PolylinePath(std::vector<Vector2i> points) {
+ segments.reserve(points.size());
+ float total_len = 0;
+ std::vector<Vector2i>::iterator pit = points.begin();
+ Vector2i p0 = *pit;
+ pit++;
+ for (;pit != points.end(); pit++) {
+ Vector2i p1 = *pit;
+ float len = distance(p0, p1);
+ total_len += len;
+ segments.push_back(PolylineSegment(p0, p1, len));
+ p0 = p1;
+ }
+ float progress = 0;
+ for (std::vector<PolylineSegment>::iterator sit = segments.begin();
+ sit != segments.end(); sit++
+ ) {
+ float ratio = sit->len / total_len;
+ progress += ratio;
+ sit->progress = progress;
+ sit->ratio = ratio;
+ }
+}
+
+Vector2i PolylinePath::solve(float t) {
+ std::vector<PolylineSegment>::iterator it = std::lower_bound(
+ segments.begin(),
+ segments.end(),
+ t
+ );
+ PolylineSegment segment = it == segments.end()?
+ segments[segments.size()-1]:
+ *it;
+
+ float r = segment.ratio;
+ float p1 = segment.progress;
+ float p0 = p1 - r;
+ float tn = (t - p0) / r;
+
+ return segment.solve(tn);
+}
+
+
+
View
@@ -0,0 +1,21 @@
+
+#ifndef POLYLINEPATH_H
+#define POLYLINEPATH_H
+
+#include <stdlib.h>
+#include <vector>
+#include "VectorTypes.h"
+#include "IPath.h"
+#include "PolylineSegment.h"
+
+class PolylinePath : public IPath {
+
+ public:
+ PolylinePath(std::vector<Vector2i> points);
+ Vector2i solve(float t);
+ private:
+ std::vector<PolylineSegment> segments;
+
+};
+
+#endif
@@ -0,0 +1,18 @@
+
+#include "PolylineSegment.h"
+
+PolylineSegment::PolylineSegment(Vector2i from, Vector2i to, float len) :
+ len(len),
+ progress(0), ratio(0),
+ from(from), to(to), diff(to - from)
+ {}
+
+Vector2i PolylineSegment::solve(float t) {
+ return from + diff * t;
+}
+
+bool PolylineSegment::operator< (float edge) const {
+ return progress < edge;
+}
+
+
View
@@ -0,0 +1,18 @@
+
+#ifndef POLYLINESEGMENT_H
+#define POLYLINESEGMENT_H
+
+#include "VectorTypes.h"
+
+class PolylineSegment {
+
+ public:
+ float len, progress, ratio;
+ Vector2i from, to, diff;
+ PolylineSegment(Vector2i from, Vector2i to, float len);
+ Vector2i solve(float t);
+ bool operator< (float edge) const;
+
+};
+
+#endif
View
@@ -15,8 +15,11 @@ Timeline::Timeline() : tickers() {
}
Timeline::~Timeline() {
- for (set<ITicker*>::iterator it = tickers.begin(); it != tickers.end(); it++)
- (*it)->stop();
+ for (set<ITicker*>::iterator it = tickers.begin(); it != tickers.end();) {
+ set<ITicker*>::iterator it2 = it;
+ it++;
+ (*it2)->stop();
+ }
}
void Timeline::register_ticker(ITicker *ticker) {
@@ -28,8 +31,11 @@ void Timeline::unregister_ticker(ITicker *ticker) {
}
void Timeline::tick(Uint32 now) {
- for (set<ITicker*>::iterator it = tickers.begin(); it != tickers.end(); it++)
- (*it)->tick(now);
+ for (set<ITicker*>::iterator it = tickers.begin(); it != tickers.end();) {
+ set<ITicker*>::iterator it2 = it;
+ it++;
+ (*it2)->tick(now);
+ }
}
Tween *Timeline::build_int_tween(IProxy<int,1> *proxy, ICompleter *completer,
View
@@ -63,6 +63,13 @@ Vector<float,DIM> operator* (const Vector<float,DIM>& t, float k) {
return res;
}
+template<int DIM>
+Vector<int,DIM> operator* (const Vector<float,DIM>& t, int k) {
+ Vector<int,DIM> res;
+ for (unsigned i=0; i<DIM; ++i) { res[i] = (int) round(t[i] * (float) k); }
+ return res;
+}
+
template<typename T,int DIM>
Vector<T,DIM> operator/ (const Vector<T,DIM>& t, float k) {
Vector<T,DIM> res;
@@ -79,4 +86,13 @@ std::ostream& operator<< (std::ostream& os, const Vector<T,DIM>& t)
return os;
}
+template<typename T,int DIM>
+float distance (const Vector<T,DIM>& lhs, const Vector<T,DIM>& rhs) {
+ Vector<T,DIM> diff = lhs - rhs;
+ float d = 0;
+ for (unsigned i=0; i<DIM; ++i) d += diff[i] * diff[i];
+ return sqrt(d);
+}
+
+
#endif
View
@@ -9,5 +9,6 @@ typedef Vector<int,2> Vector2i;
typedef Vector<int,4> Vector4i;
typedef Vector<float,1> Vector1f;
+typedef Vector<float,2> Vector2f;
#endif
@@ -22,7 +22,7 @@ class PerlDirectProxy : public IProxy<T,DIM> {
~PerlDirectProxy() {
}
void update(Vector<int,1>& value) {
- SvIV_set((SV*) target, value[0]);
+ SvIV_set(target, value[0]);
}
void update(Vector<float,1>& value) {
SvNV_set(target, value[0]);
@@ -2,12 +2,15 @@
#ifndef PERLPATHFACTORY_H
#define PERLPATHFACTORY_H
+#include <vector>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "VectorTypes.h"
#include "IPath.h"
#include "LinearPath.h"
+#include "CircularPath.h"
+#include "PolylinePath.h"
Vector2i av_to_vec_2D(SV *rv) {
AV* arr = (AV*) SvRV(rv);
@@ -17,16 +20,50 @@ Vector2i av_to_vec_2D(SV *rv) {
return v;
}
-IPath *Build_Path(int path_type, SV *path_args) {
+IPath *Build_Path_Linear(SV *path_args) {
HV* args = (HV*) SvRV(path_args);
SV** from_sv = hv_fetch(args, "from", 4, 0);
SV** to_sv = hv_fetch(args, "to" , 2, 0);
Vector2i from = av_to_vec_2D(*from_sv);
Vector2i to = av_to_vec_2D(*to_sv);
- IPath *path = new LinearPath(from, to);
- return path;
+ return new LinearPath(from, to);
+}
+
+IPath *Build_Path_Circular(SV *path_args) {
+ HV* args = (HV*) SvRV(path_args);
+ SV** center = hv_fetch(args, "center", 6, 0);
+ SV** radius = hv_fetch(args, "radius", 6, 0);
+ SV** from_angle = hv_fetch(args, "from" , 4, 0);
+ SV** to_angle = hv_fetch(args, "to" , 2, 0);
+ return new CircularPath(
+ av_to_vec_2D(*center),
+ (int) SvIV(*radius),
+ (float) SvNV(*from_angle),
+ (float) SvNV(*to_angle)
+ );
}
+IPath *Build_Path_Polyline(SV *path_args) {
+ AV* args = (AV*) SvRV(path_args);
+ int len = av_len(args) + 1;
+ std::vector<Vector2i> points(len);
+ int i;
+ for (i = 0; i < len; i++) {
+ SV** point_arr_ref = av_fetch(args, i, 0);
+ Vector2i point = av_to_vec_2D(*point_arr_ref);
+ points[i] = point;
+ }
+ return new PolylinePath(points);
+}
+static IPath* (*Path_Table[3]) (SV*) = {
+ Build_Path_Linear,
+ Build_Path_Circular,
+ Build_Path_Polyline
+};
+
+IPath *Build_Path(int path_type, SV *path_args) {
+ return Path_Table[path_type](path_args);
+}
#endif

0 comments on commit e26a926

Please sign in to comment.