~ubuntu-branches/ubuntu/precise/frogatto/precise

« back to all changes in this revision

Viewing changes to src/current_generator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Dmitry E. Oboukhov
  • Date: 2010-07-21 16:21:45 UTC
  • Revision ID: james.westby@ubuntu.com-20100721162145-zid0u93fm3xz73gh
Tags: upstream-1.0+dfsg1
ImportĀ upstreamĀ versionĀ 1.0+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <iostream>
 
2
#include <math.h>
 
3
 
 
4
#include "current_generator.hpp"
 
5
#include "formatter.hpp"
 
6
#include "wml_node.hpp"
 
7
#include "wml_utils.hpp"
 
8
 
 
9
current_generator_ptr current_generator::create(wml::const_node_ptr node)
 
10
{
 
11
        const std::string& type = node->attr("type");
 
12
        if(type == "radial") {
 
13
                return current_generator_ptr(new radial_current_generator(node));
 
14
        } else if(type == "rect") {
 
15
                return current_generator_ptr(new rect_current_generator(node));
 
16
        } else {
 
17
                return NULL;
 
18
        }
 
19
}
 
20
 
 
21
current_generator::~current_generator() {
 
22
}
 
23
 
 
24
variant current_generator::get_value(const std::string& key) const
 
25
{
 
26
        return variant();
 
27
}
 
28
 
 
29
radial_current_generator::radial_current_generator(int intensity, int radius)
 
30
  : intensity_(intensity), radius_(radius)
 
31
{}
 
32
 
 
33
radial_current_generator::radial_current_generator(wml::const_node_ptr node)
 
34
  : intensity_(wml::get_int(node, "intensity")),
 
35
    radius_(wml::get_int(node, "radius"))
 
36
{}
 
37
 
 
38
void radial_current_generator::generate(int center_x, int center_y, int target_x, int target_y, int target_mass, int* velocity_x, int* velocity_y) {
 
39
        if(center_x == target_x && center_y == target_y) {
 
40
                return;
 
41
        }
 
42
 
 
43
        const float xdiff = target_x - center_x;
 
44
        const float ydiff = target_y - center_y;
 
45
        if(abs(xdiff) >= radius_ || abs(ydiff) > radius_) {
 
46
                return;
 
47
        }
 
48
 
 
49
        const float distance = sqrt(xdiff*xdiff + ydiff*ydiff);
 
50
        if(distance >= radius_) {
 
51
                return;
 
52
        }
 
53
 
 
54
        const float intensity = intensity_*(1.0 - distance/radius_);
 
55
        const float xdiff_normalized = xdiff/(abs(xdiff) + abs(ydiff));
 
56
        const float ydiff_normalized = ydiff/(abs(xdiff) + abs(ydiff));
 
57
 
 
58
        std::cerr << "DO_CURRENT: " << center_x << "," << center_y << " ~ " << target_x << "," << target_y << ": "<< intensity << " x " << xdiff_normalized << "," << ydiff_normalized << "\n";
 
59
        *velocity_x += xdiff_normalized*intensity;
 
60
        *velocity_y += ydiff_normalized*intensity;
 
61
}
 
62
 
 
63
wml::node_ptr radial_current_generator::write() const
 
64
{
 
65
        wml::node_ptr result(new wml::node("current_generator"));
 
66
        result->set_attr("type", "radial");
 
67
        result->set_attr("intensity", formatter() << intensity_);
 
68
        result->set_attr("radius", formatter() << radius_);
 
69
        return result;
 
70
}
 
71
 
 
72
rect_current_generator::rect_current_generator(const rect& r, int xvelocity, int yvelocity, int strength)
 
73
  : rect_(r), xvelocity_(xvelocity), yvelocity_(yvelocity), strength_(strength)
 
74
{}
 
75
 
 
76
rect_current_generator::rect_current_generator(wml::const_node_ptr node)
 
77
  : rect_(node->attr("rect")), xvelocity_(wml::get_int(node, "xvelocity")), yvelocity_(wml::get_int(node, "yvelocity")), strength_(wml::get_int(node, "strength"))
 
78
{}
 
79
 
 
80
void rect_current_generator::generate(int center_x, int center_y, int target_x, int target_y, int target_mass, int* velocity_x, int* velocity_y)
 
81
{
 
82
        const int strength = strength_;
 
83
        if(point_in_rect(point(target_x, target_y), rect_)) {
 
84
                if(xvelocity_ > 0 && *velocity_x < xvelocity_) {
 
85
                        int amount = (xvelocity_ - std::max(0, *velocity_x))*strength/(target_mass*1000);
 
86
                        const int distance = rect_.x2() - target_x;
 
87
                        amount = (amount*distance*distance)/(rect_.h()*rect_.h());
 
88
                        *velocity_x += amount;
 
89
                        if(*velocity_x > xvelocity_) {
 
90
                                *velocity_x = xvelocity_;
 
91
                        }
 
92
                } else if(xvelocity_ < 0 && *velocity_x > xvelocity_) {
 
93
                        int amount = (xvelocity_ - std::min(0, *velocity_x))*strength/(target_mass*1000);
 
94
                        const int distance = target_x - rect_.x();
 
95
                        amount = (amount*distance*distance)/(rect_.h()*rect_.h());
 
96
                        *velocity_x += amount;
 
97
                        if(*velocity_x < xvelocity_) {
 
98
                                *velocity_x = xvelocity_;
 
99
                        }
 
100
                }
 
101
 
 
102
                if(yvelocity_ > 0 && *velocity_y < yvelocity_) {
 
103
                        int amount = (yvelocity_ - std::max(0, *velocity_y))*strength/(target_mass*1000);
 
104
                        const int distance = rect_.y2() - target_y;
 
105
                        amount = (amount*distance*distance)/(rect_.h()*rect_.h());
 
106
                        *velocity_y += amount;
 
107
                        if(*velocity_y > yvelocity_) {
 
108
                                *velocity_y = yvelocity_;
 
109
                        }
 
110
                } else if(yvelocity_ < 0 && *velocity_y > yvelocity_) {
 
111
                        int amount = yvelocity_*strength/(target_mass*1000);
 
112
                        const int distance = target_y - rect_.y();
 
113
//                      amount = (amount*distance*distance)/(rect_.h()*rect_.h());
 
114
                        std::cerr << "DIST: " << distance << "/" << rect_.h() << " " << *velocity_y << "\n";
 
115
                        if(distance < rect_.h()/2 && *velocity_y > 0) {
 
116
                                std::cerr << "CANCEL\n";
 
117
                                amount = 0;
 
118
                        }
 
119
                        *velocity_y += amount;
 
120
                        if(*velocity_y < yvelocity_) {
 
121
//                              *velocity_y = yvelocity_;
 
122
                        }
 
123
                }
 
124
        }
 
125
}
 
126
 
 
127
wml::node_ptr rect_current_generator::write() const
 
128
{
 
129
        wml::node_ptr node(new wml::node("current_generator"));
 
130
        node->set_attr("type", "rect");
 
131
        node->set_attr("rect", rect_.to_string());
 
132
        node->set_attr("xvelocity", formatter() << xvelocity_);
 
133
        node->set_attr("yvelocity", formatter() << yvelocity_);
 
134
        node->set_attr("strength", formatter() << strength_);
 
135
        return node;
 
136
}