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