Mondschein Engine  0.3.0
normgrid.cpp
1 /* Mondschein Engine is a fast, powerful, and easy-to-use 3D realtime rendering engine.
2  *
3  * Copyright (C) 2009-2013 by Andreas Amereller
4  * E-Mail: andreas.amereller.dev@googlemail.com
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "core/normgrid.h"
22 #include "core/aitken_neville.h"
23 
24 using namespace mondschein;
25 using namespace math;
26 
27 std::array<Eigen::Vector3d,2> make_triangle(const Eigen::Vector3d &_a,const Eigen::Vector3d &_b,const Eigen::Vector3d &_c);
28 Eigen::Vector3d calc_normal(const std::array<Eigen::Vector3d,2> &_t);
29 Eigen::Vector3d interpolate_vector(const std::array<Eigen::Vector3d,4> &_v);
30 void expand(std::vector<std::vector<Eigen::Vector3d> > &_grid);
31 
32 std::array<Eigen::Vector3d,2> make_triangle(const Eigen::Vector3d &_a,const Eigen::Vector3d &_b,const Eigen::Vector3d &_c)
33 {
34  std::array<Eigen::Vector3d,2> t;
35  t.at(0)=(_b-_a);
36  t.at(1)=(_c-_a);
37  return t;
38 }
39 
40 Eigen::Vector3d calc_normal(const std::array<Eigen::Vector3d,2> &_t)
41 {
42  return _t.at(0).cross(_t.at(1)).normalized();
43 }
44 
45 Eigen::Vector3d interpolate_vector(const std::array<Eigen::Vector3d,4> &_v)
46 {
47  Eigen::Vector3d v(0.0,0.0,0.0);
48  for (uint32 i=0; i<3; ++i)
49  {
50  std::map<float64,float64> p;
51  for (uint32 j=0; j<3; j++) p.insert(std::make_pair(j,_v.at(j)(i)));
52  Aitken_Neville_p ip(new Aitken_Neville(p));
53  v(i)=ip->interpolate(-1.0);
54  }
55  return v;
56 }
57 
58 void expand(std::vector<std::vector<Eigen::Vector3d> > &_grid)
59 {
60  std::vector<Eigen::Vector3d> b,e;
61  std::array<Eigen::Vector3d,4> a;
62  uint32 s1=_grid.size();
63  uint32 s2=_grid.at(0).size();
64  for (uint32 j=0; j<s2; ++j)
65  {
66  for (uint32 k=0; k<4; ++k) a.at(k)=_grid.at(k).at(j);
67  b.push_back(interpolate_vector(a));
68  for (uint32 k=0; k<4; ++k) a.at(k)=_grid.at(s1-1-k).at(j);
69  e.push_back(interpolate_vector(a));
70  }
71  _grid.insert(_grid.begin(),b);
72  _grid.push_back(e);
73  s1=_grid.size();
74  s2=_grid.at(0).size();
75  for (uint32 i=0; i<s1; ++i)
76  {
77  for (uint32 k=0; k<4; ++k) a.at(k)=_grid.at(i).at(k);
78  _grid.at(i).insert(_grid.at(i).begin(),interpolate_vector(a));
79  for (uint32 k=0; k<4; ++k) a.at(k)=_grid.at(i).at(s2-2-k);
80  _grid.at(i).push_back(interpolate_vector(a));
81  }
82  return;
83 }
84 
85 Normal_Grid::Normal_Grid()
86 {
87  return;
88 }
89 
90 Normal_Grid::Normal_Grid(Normal_Grid_c _nc)
91 {
92  return;
93 }
94 
95 Normal_Grid::~Normal_Grid()
96 {
97  return;
98 }
99 
100 Normal_Grid &Normal_Grid::operator=(Normal_Grid_c _nc)
101 {
102  return *this;
103 }
104 
105 std::vector<Eigen::Vector3d> Normal_Grid::flat(const std::vector<std::vector<Eigen::Vector3d> > &_grid)
106 {
107  std::vector<Eigen::Vector3d> n;
108  for (uint32 i=0; i<_grid.size()-1; ++i)
109  {
110  for (uint32 j=0; j<_grid.at(i).size()-1; ++j)
111  {
112  n.push_back(calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j),_grid.at(i).at(j+1))));
113  n.push_back(calc_normal(make_triangle(_grid.at(i+1).at(j+1),_grid.at(i).at(j+1),_grid.at(i+1).at(j))));
114  }
115  }
116  return n;
117 }
118 
119 std::vector<Eigen::Vector3d> Normal_Grid::flat_inv(const std::vector<std::vector<Eigen::Vector3d> > &_grid)
120 {
121  std::vector<Eigen::Vector3d> n;
122  for (uint32 i=0; i<_grid.size()-1; ++i)
123  {
124  for (uint32 j=0; j<_grid.at(i).size()-1; ++j)
125  {
126  n.push_back(calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j),_grid.at(i).at(j+1)))*(-1));
127  n.push_back(calc_normal(make_triangle(_grid.at(i+1).at(j+1),_grid.at(i).at(j+1),_grid.at(i+1).at(j)))*(-1));
128  }
129  }
130  return n;
131 }
132 
133 std::vector<Eigen::Vector3d> Normal_Grid::intermediate(std::vector<std::vector<Eigen::Vector3d> > _grid)
134 {
135  expand(_grid);
136  std::vector<Eigen::Vector3d> n;
137  Eigen::Vector3d tn;
138  for (uint32 i=1; i<_grid.size()-1; ++i)
139  {
140  for (uint32 j=1; j<_grid.at(i).size()-1; ++j)
141  {
142  tn=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j),_grid.at(i+1).at(j+1)));
143  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j+1),_grid.at(i).at(j+1)));
144  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j+1),_grid.at(i-1).at(j+1)));
145  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j+1),_grid.at(i-1).at(j)));
146  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j),_grid.at(i-1).at(j-1)));
147  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j-1),_grid.at(i).at(j-1)));
148  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j-1),_grid.at(i).at(j+1)));
149  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j+1),_grid.at(i+1).at(j))).normalized();
150  n.push_back(tn);
151  }
152  }
153  return n;
154 }
155 
156 std::vector<Eigen::Vector3d> Normal_Grid::intermediate_inv(std::vector<std::vector<Eigen::Vector3d> > _grid)
157 {
158  expand(_grid);
159  std::vector<Eigen::Vector3d> n;
160  Eigen::Vector3d tn;
161  for (uint32 i=0; i<_grid.size()-1; ++i)
162  {
163  for (uint32 j=0; j<_grid.at(i).size()-1; ++j)
164  {
165  tn=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j),_grid.at(i+1).at(j+1)));
166  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i+1).at(j+1),_grid.at(i).at(j+1)));
167  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j+1),_grid.at(i-1).at(j+1)));
168  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j+1),_grid.at(i-1).at(j)));
169  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j),_grid.at(i-1).at(j-1)));
170  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i-1).at(j-1),_grid.at(i).at(j-1)));
171  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j-1),_grid.at(i).at(j+1)));
172  tn+=calc_normal(make_triangle(_grid.at(i).at(j),_grid.at(i).at(j+1),_grid.at(i+1).at(j))).normalized();
173  n.push_back(tn);
174  }
175  }
176  return n;
177 }