00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_DRAGPLANES_H)
00023 #define INCLUDED_DRAGPLANES_H
00024
00025 #include "selectable.h"
00026 #include "selectionlib.h"
00027 #include "math/aabb.h"
00028 #include "math/line.h"
00029
00030
00031 inline Vector3 translation_to_local (const Vector3& translation, const Matrix4& local)
00032 {
00033 return matrix4_get_translation_vec3(matrix4_multiplied_by_matrix4(matrix4_translated_by_vec3(matrix4_transposed(
00034 local), translation), local));
00035 }
00036
00037
00038 inline Vector3 translation_from_local (const Vector3& translation, const Matrix4& local)
00039 {
00040 return matrix4_get_translation_vec3(matrix4_multiplied_by_matrix4(matrix4_translated_by_vec3(local, translation),
00041 matrix4_transposed(local)));
00042 }
00043
00044 class DragPlanes
00045 {
00046 public:
00047 ObservedSelectable m_selectable_right;
00048 ObservedSelectable m_selectable_left;
00049 ObservedSelectable m_selectable_front;
00050 ObservedSelectable m_selectable_back;
00051 ObservedSelectable m_selectable_top;
00052 ObservedSelectable m_selectable_bottom;
00053 AABB m_bounds;
00054
00055 DragPlanes (const SelectionChangeCallback& onchanged) :
00056 m_selectable_right(onchanged), m_selectable_left(onchanged), m_selectable_front(onchanged),
00057 m_selectable_back(onchanged), m_selectable_top(onchanged), m_selectable_bottom(onchanged)
00058 {
00059 }
00060 bool isSelected () const
00061 {
00062 return m_selectable_right.isSelected() || m_selectable_left.isSelected() || m_selectable_front.isSelected()
00063 || m_selectable_back.isSelected() || m_selectable_top.isSelected()
00064 || m_selectable_bottom.isSelected();
00065 }
00066 void setSelected (bool selected)
00067 {
00068 m_selectable_right.setSelected(selected);
00069 m_selectable_left.setSelected(selected);
00070 m_selectable_front.setSelected(selected);
00071 m_selectable_back.setSelected(selected);
00072 m_selectable_top.setSelected(selected);
00073 m_selectable_bottom.setSelected(selected);
00074 }
00075 void selectPlanes (const AABB& aabb, Selector& selector, SelectionTest& test,
00076 const PlaneCallback& selectedPlaneCallback, const Matrix4& rotation = g_matrix4_identity)
00077 {
00078 Line line(test.getNear(), test.getFar());
00079 Vector3 corners[8];
00080 aabb_corners_oriented(aabb, rotation, corners);
00081
00082 Plane3 planes[6];
00083 aabb_planes_oriented(aabb, rotation, planes);
00084
00085 for (Vector3* i = corners; i != corners + 8; ++i) {
00086 *i = line_closest_point(line, *i) - (*i);
00087 }
00088
00089 if (planes[0].normal().dot(corners[1]) > 0 && planes[0].normal().dot(corners[2]) > 0
00090 && planes[0].normal().dot(corners[5]) > 0 && planes[0].normal().dot(corners[6]) > 0) {
00091 Selector_add(selector, m_selectable_right);
00092 selectedPlaneCallback(planes[0]);
00093 }
00094 if (planes[1].normal().dot(corners[0]) > 0 && planes[1].normal().dot(corners[3]) > 0
00095 && planes[1].normal().dot(corners[4]) > 0 && planes[1].normal().dot(corners[7]) > 0) {
00096 Selector_add(selector, m_selectable_left);
00097 selectedPlaneCallback(planes[1]);
00098 }
00099 if (planes[2].normal().dot(corners[0]) > 0 && planes[2].normal().dot(corners[1]) > 0
00100 && planes[2].normal().dot(corners[4]) > 0 && planes[2].normal().dot(corners[5]) > 0) {
00101 Selector_add(selector, m_selectable_front);
00102 selectedPlaneCallback(planes[2]);
00103 }
00104 if (planes[3].normal().dot(corners[2]) > 0 && planes[3].normal().dot(corners[3]) > 0
00105 && planes[3].normal().dot(corners[6]) > 0 && planes[3].normal().dot(corners[7]) > 0) {
00106 Selector_add(selector, m_selectable_back);
00107 selectedPlaneCallback(planes[3]);
00108 }
00109 if (planes[4].normal().dot(corners[0]) > 0 && planes[4].normal().dot(corners[1]) > 0
00110 && planes[4].normal().dot(corners[2]) > 0 && planes[4].normal().dot(corners[3]) > 0) {
00111 Selector_add(selector, m_selectable_top);
00112 selectedPlaneCallback(planes[4]);
00113 }
00114 if (planes[5].normal().dot(corners[4]) > 0 && planes[5].normal().dot(corners[5]) > 0
00115 && planes[5].normal().dot(corners[6]) > 0 && planes[5].normal().dot(corners[7]) > 0) {
00116 Selector_add(selector, m_selectable_bottom);
00117 selectedPlaneCallback(planes[5]);
00118 }
00119
00120 m_bounds = aabb;
00121 }
00122 void selectReversedPlanes (const AABB& aabb, Selector& selector, const SelectedPlanes& selectedPlanes,
00123 const Matrix4& rotation = g_matrix4_identity)
00124 {
00125 Plane3 planes[6];
00126 aabb_planes_oriented(aabb, rotation, planes);
00127
00128 if (selectedPlanes.contains(plane3_flipped(planes[0]))) {
00129 Selector_add(selector, m_selectable_right);
00130 }
00131 if (selectedPlanes.contains(plane3_flipped(planes[1]))) {
00132 Selector_add(selector, m_selectable_left);
00133 }
00134 if (selectedPlanes.contains(plane3_flipped(planes[2]))) {
00135 Selector_add(selector, m_selectable_front);
00136 }
00137 if (selectedPlanes.contains(plane3_flipped(planes[3]))) {
00138 Selector_add(selector, m_selectable_back);
00139 }
00140 if (selectedPlanes.contains(plane3_flipped(planes[4]))) {
00141 Selector_add(selector, m_selectable_top);
00142 }
00143 if (selectedPlanes.contains(plane3_flipped(planes[5]))) {
00144 Selector_add(selector, m_selectable_bottom);
00145 }
00146 }
00147 AABB evaluateResize (const Vector3& translation) const
00148 {
00149 Vector3 min = m_bounds.origin - m_bounds.extents;
00150 Vector3 max = m_bounds.origin + m_bounds.extents;
00151 if (m_bounds.extents[0] != 0) {
00152 if (m_selectable_right.isSelected()) {
00153 max[0] += translation[0];
00154 }
00155 if (m_selectable_left.isSelected()) {
00156 min[0] += translation[0];
00157 }
00158 }
00159 if (m_bounds.extents[1] != 0) {
00160 if (m_selectable_front.isSelected()) {
00161 max[1] += translation[1];
00162 }
00163 if (m_selectable_back.isSelected()) {
00164 min[1] += translation[1];
00165 }
00166 }
00167 if (m_bounds.extents[2] != 0) {
00168 if (m_selectable_top.isSelected()) {
00169 max[2] += translation[2];
00170 }
00171 if (m_selectable_bottom.isSelected()) {
00172 min[2] += translation[2];
00173 }
00174 }
00175
00176 return AABB(vector3_mid(min, max), (max - min) * 0.5);
00177 }
00178 AABB evaluateResize (const Vector3& translation, const Matrix4& rotation) const
00179 {
00180 AABB aabb(evaluateResize(translation_to_local(translation, rotation)));
00181 aabb.origin = m_bounds.origin + translation_from_local(aabb.origin - m_bounds.origin, rotation);
00182 return aabb;
00183 }
00184 Matrix4 evaluateTransform (const Vector3& translation) const
00185 {
00186 AABB aabb(evaluateResize(translation));
00187 Vector3 scale(m_bounds.extents[0] != 0 ? aabb.extents[0] / m_bounds.extents[0] : 1, m_bounds.extents[1]
00188 != 0 ? aabb.extents[1] / m_bounds.extents[1] : 1, m_bounds.extents[2] != 0 ? aabb.extents[2]
00189 / m_bounds.extents[2] : 1);
00190
00191 Matrix4 matrix = Matrix4::getTranslation(aabb.origin - m_bounds.origin);
00192 matrix4_pivoted_scale_by_vec3(matrix, scale, m_bounds.origin);
00193
00194 return matrix;
00195 }
00196 };
00197
00198 #endif