|
Blender
V2.59
|
00001 /* 00002 * $Id: KX_SG_NodeRelationships.cpp 35171 2011-02-25 13:35:59Z jesterking $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include "KX_SG_NodeRelationships.h" 00035 00044 KX_NormalParentRelation * 00045 KX_NormalParentRelation:: 00046 New( 00047 ) { 00048 return new KX_NormalParentRelation(); 00049 } 00050 00051 bool 00052 KX_NormalParentRelation:: 00053 UpdateChildCoordinates( 00054 SG_Spatial * child, 00055 const SG_Spatial * parent, 00056 bool& parentUpdated 00057 ){ 00058 MT_assert(child != NULL); 00059 00060 if (!parentUpdated && !child->IsModified()) 00061 return false; 00062 00063 parentUpdated = true; 00064 00065 if (parent==NULL) { /* Simple case */ 00066 child->SetWorldFromLocalTransform(); 00067 child->ClearModified(); 00068 return true; //false; 00069 } 00070 else { 00071 // the childs world locations which we will update. 00072 const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); 00073 const MT_Point3 & p_world_pos = parent->GetWorldPosition(); 00074 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); 00075 00076 child->SetWorldScale(p_world_scale * child->GetLocalScale()); 00077 child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation()); 00078 child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition())); 00079 child->ClearModified(); 00080 return true; 00081 } 00082 } 00083 00084 SG_ParentRelation * 00085 KX_NormalParentRelation:: 00086 NewCopy( 00087 ){ 00088 return new KX_NormalParentRelation(); 00089 } 00090 00091 KX_NormalParentRelation:: 00092 ~KX_NormalParentRelation( 00093 ){ 00094 //nothing to do 00095 } 00096 00097 00098 KX_NormalParentRelation:: 00099 KX_NormalParentRelation( 00100 ){ 00101 // nothing to do 00102 } 00103 00109 KX_VertexParentRelation * 00110 KX_VertexParentRelation:: 00111 New( 00112 ){ 00113 return new KX_VertexParentRelation(); 00114 } 00115 00120 bool 00121 KX_VertexParentRelation:: 00122 UpdateChildCoordinates( 00123 SG_Spatial * child, 00124 const SG_Spatial * parent, 00125 bool& parentUpdated 00126 ){ 00127 00128 MT_assert(child != NULL); 00129 00130 if (!parentUpdated && !child->IsModified()) 00131 return false; 00132 00133 child->SetWorldScale(child->GetLocalScale()); 00134 00135 if (parent) 00136 child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition()); 00137 else 00138 child->SetWorldPosition(child->GetLocalPosition()); 00139 00140 child->SetWorldOrientation(child->GetLocalOrientation()); 00141 child->ClearModified(); 00142 return true; //parent != NULL; 00143 } 00144 00149 SG_ParentRelation * 00150 KX_VertexParentRelation:: 00151 NewCopy( 00152 ){ 00153 return new KX_VertexParentRelation(); 00154 }; 00155 00156 KX_VertexParentRelation:: 00157 ~KX_VertexParentRelation( 00158 ){ 00159 //nothing to do 00160 } 00161 00162 00163 KX_VertexParentRelation:: 00164 KX_VertexParentRelation( 00165 ){ 00166 //nothing to do 00167 } 00168 00169 00174 KX_SlowParentRelation * 00175 KX_SlowParentRelation:: 00176 New( 00177 MT_Scalar relaxation 00178 ){ 00179 return new KX_SlowParentRelation(relaxation); 00180 } 00181 00186 bool 00187 KX_SlowParentRelation:: 00188 UpdateChildCoordinates( 00189 SG_Spatial * child, 00190 const SG_Spatial * parent, 00191 bool& parentUpdated 00192 ){ 00193 MT_assert(child != NULL); 00194 00195 // the child will move even if the parent is not 00196 parentUpdated = true; 00197 00198 const MT_Vector3 & child_scale = child->GetLocalScale(); 00199 const MT_Point3 & child_pos = child->GetLocalPosition(); 00200 const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); 00201 00202 // the childs world locations which we will update. 00203 00204 MT_Vector3 child_w_scale; 00205 MT_Point3 child_w_pos; 00206 MT_Matrix3x3 child_w_rotation; 00207 00208 if (parent) { 00209 00210 // This is a slow parent relation 00211 // first compute the normal child world coordinates. 00212 00213 MT_Vector3 child_n_scale; 00214 MT_Point3 child_n_pos; 00215 MT_Matrix3x3 child_n_rotation; 00216 00217 const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); 00218 const MT_Point3 & p_world_pos = parent->GetWorldPosition(); 00219 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); 00220 00221 child_n_scale = p_world_scale * child_scale; 00222 child_n_rotation = p_world_rotation * child_rotation; 00223 00224 child_n_pos = p_world_pos + p_world_scale * 00225 (p_world_rotation * child_pos); 00226 00227 00228 if (m_initialized) { 00229 00230 // get the current world positions 00231 00232 child_w_scale = child->GetWorldScaling(); 00233 child_w_pos = child->GetWorldPosition(); 00234 child_w_rotation = child->GetWorldOrientation(); 00235 00236 // now 'interpolate' the normal coordinates with the last 00237 // world coordinates to get the new world coordinates. 00238 00239 MT_Scalar weight = MT_Scalar(1)/(m_relax + 1); 00240 child_w_scale = (m_relax * child_w_scale + child_n_scale) * weight; 00241 child_w_pos = (m_relax * child_w_pos + child_n_pos) * weight; 00242 // for rotation we must go through quaternion 00243 MT_Quaternion child_w_quat = child_w_rotation.getRotation().slerp(child_n_rotation.getRotation(), weight); 00244 child_w_rotation.setRotation(child_w_quat); 00245 //FIXME: update physics controller. 00246 } else { 00247 child_w_scale = child_n_scale; 00248 child_w_pos = child_n_pos; 00249 child_w_rotation = child_n_rotation; 00250 m_initialized = true; 00251 } 00252 00253 } else { 00254 00255 child_w_scale = child_scale; 00256 child_w_pos = child_pos; 00257 child_w_rotation = child_rotation; 00258 } 00259 00260 child->SetWorldScale(child_w_scale); 00261 child->SetWorldPosition(child_w_pos); 00262 child->SetWorldOrientation(child_w_rotation); 00263 child->ClearModified(); 00264 // this node must always be updated, so reschedule it for next time 00265 child->ActivateRecheduleUpdateCallback(); 00266 00267 return true; //parent != NULL; 00268 } 00269 00274 SG_ParentRelation * 00275 KX_SlowParentRelation:: 00276 NewCopy( 00277 ){ 00278 return new KX_SlowParentRelation(m_relax); 00279 } 00280 00281 KX_SlowParentRelation:: 00282 KX_SlowParentRelation( 00283 MT_Scalar relaxation 00284 ): 00285 m_relax(relaxation), 00286 m_initialized(false) 00287 { 00288 //nothing to do 00289 } 00290 00291 KX_SlowParentRelation:: 00292 ~KX_SlowParentRelation( 00293 ){ 00294 //nothing to do 00295 } 00296 00297 00298 00299