1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
5 #include "CharacterEditor\ModelViewportCE.h"
6 #include "CharacterEditor\CharPanel_Animation.h"
7 #include <CryAnimation/ICryAnimation.h>
9 #include <Cry3DEngine/I3DEngine.h>
10 #include <CryPhysics/IPhysics.h>
11 #include <CrySystem/ITimer.h>
12 #include <CryInput/IInput.h>
13 #include <CryRenderer/IRenderAuxGeom.h>
17 //------------------------------------------------------------------------------
18 //--- simple player-control test-application ---
19 //------------------------------------------------------------------------------
20 void CModelViewportCE::PlayerControl_UnitTest(ICharacterInstance
* pInstance
, const SRendParams
& rRP
, const SRenderingPassInfo
& passInfo
)
22 IRenderAuxGeom
* pAuxGeom
= m_renderer
->GetIRenderAuxGeom();
23 pAuxGeom
->SetRenderFlags(e_Def3DPublicRenderflags
);
24 f32 FrameTime
= GetIEditor()->GetSystem()->GetITimer()->GetFrameTime();
26 ISkeletonAnim
* pISkeletonAnim
= pInstance
->GetISkeletonAnim();
27 ISkeletonPose
* pISkeletonPose
= pInstance
->GetISkeletonPose();
32 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
33 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x00, 0xff, 0x1f, 0xff), eBBD_Extremes_Color_Encoded
);
35 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
36 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x00, 0x0f, 0x4f, 0xff), eBBD_Extremes_Color_Encoded
);
37 wpos
= Vec3(5.5f
, 2, 0);
38 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
39 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x00, 0x0f, 0x7f, 0xff), eBBD_Extremes_Color_Encoded
);
42 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
43 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x7f, 0x7f, 0x7f, 0xff), eBBD_Extremes_Color_Encoded
);
45 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
46 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x7f, 0x7f, 0x7f, 0xff), eBBD_Extremes_Color_Encoded
);
47 wpos
= Vec3(0, 11, 0);
48 aabb
= AABB(Vec3(-0.2f
, -0.2f
, -0.00f
) + wpos
, Vec3(+0.2f
, +0.2f
, +2.0f
) + wpos
);
49 pAuxGeom
->DrawAABB(aabb
, Matrix34(IDENTITY
), 1, RGBA8(0x7f, 0x7f, 0x7f, 0xff), eBBD_Extremes_Color_Encoded
);
52 float color1
[4] = { 1, 1, 1, 1 };
54 //set the required callbacks
55 int PostProcessCallback_PlayControl(ICharacterInstance
* pInstance
, void* pPlayer
);
56 pISkeletonPose
->SetPostProcessCallback(PostProcessCallback_PlayControl
, this);
57 pISkeletonAnim
->SetEventCallback(0, this);
60 PlayerControlHuman(m_absLookDirectionXY
, 0, 0);
61 PlayerControlCamera();
66 //update the skeleton pose
67 const CCamera
& camera
= GetCamera();
68 float fDistance
= (camera
.GetPosition() - m_PhysicalLocation
.t
).GetLength();
69 float fZoomFactor
= 0.001f
+ 0.999f
* (RAD2DEG(camera
.GetFov()) / 60.f
);
71 SAnimationProcessParams params
;
72 params
.locationAnimation
= m_PhysicalLocation
;
74 params
.zoomAdjustedDistanceFromCamera
= fDistance
* fZoomFactor
;
75 ExternalPostProcessing(pInstance
);
76 pInstance
->StartAnimationProcessing(params
);
77 pInstance
->FinishAnimationComputations();
80 m_AnimatedCharacterMat
= Matrix34(m_PhysicalLocation
);
82 rp
.pMatrix
= &m_AnimatedCharacterMat
;
83 rp
.pPrevMatrix
= &m_AnimatedCharacterMat
;
84 rp
.fDistance
= (m_PhysicalLocation
.t
- m_absCameraPos
).GetLength();
85 pInstance
->Render(rp
, QuatTS(IDENTITY
), passInfo
);
88 Vec3 absAxisX
= m_PhysicalLocation
.GetColumn0();
89 Vec3 absAxisY
= m_PhysicalLocation
.GetColumn1();
90 Vec3 absAxisZ
= m_PhysicalLocation
.GetColumn2();
91 Vec3 absRootPos
= m_PhysicalLocation
.t
+ pISkeletonPose
->GetAbsJointByID(0).t
;
92 pAuxGeom
->DrawLine(absRootPos
, RGBA8(0xff, 0x00, 0x00, 0x00), absRootPos
+ m_PhysicalLocation
.GetColumn0() * 2.0f
, RGBA8(0x00, 0x00, 0x00, 0x00));
93 pAuxGeom
->DrawLine(absRootPos
, RGBA8(0x00, 0xff, 0x00, 0x00), absRootPos
+ m_PhysicalLocation
.GetColumn1() * 2.0f
, RGBA8(0x00, 0x00, 0x00, 0x00));
94 pAuxGeom
->DrawLine(absRootPos
, RGBA8(0x00, 0x00, 0xff, 0x00), absRootPos
+ m_PhysicalLocation
.GetColumn2() * 2.0f
, RGBA8(0x00, 0x00, 0x00, 0x00));
96 //---------------------------------------
97 //--- draw the path of the past
98 //---------------------------------------
99 uint32 numEntries
= m_arrAnimatedCharacterPath
.size();
100 for (int32 i
= (numEntries
- 2); i
> -1; i
--)
101 m_arrAnimatedCharacterPath
[i
+ 1] = m_arrAnimatedCharacterPath
[i
];
102 m_arrAnimatedCharacterPath
[0] = m_PhysicalLocation
.t
;
103 for (uint32 i
= 0; i
< numEntries
; i
++)
105 aabb
.min
= Vec3(-0.01f
, -0.01f
, -0.01f
) + m_arrAnimatedCharacterPath
[i
];
106 aabb
.max
= Vec3(+0.01f
, +0.01f
, +0.01f
) + m_arrAnimatedCharacterPath
[i
];
107 pAuxGeom
->DrawAABB(aabb
, 1, RGBA8(0x00, 0x00, 0xff, 0x00), eBBD_Extremes_Color_Encoded
);
113 GetIEditor()->GetSystem()->GetIConsole()->GetCVar("ca_DrawSkeleton")->Set(mv_showSkeleton
);
116 //--------------------------------------------------------------------------
118 void CModelViewportCE::PlayerControlIO()
121 IInput
* pIInput
= GetISystem()->GetIInput(); // Cache IInput pointer.
122 pIInput
->Update(true);
124 //-------------------------------------------------------------------
125 //------- Keyboard and Game-Pad handling ---------
126 //-------------------------------------------------------------------
127 m_key_SPACE
= m_key_W
= m_key_A
= m_key_D
= m_key_S
= 0;
128 if (CheckVirtualKey(VK_UP
) || CheckVirtualKey('W')) m_key_W
= 1;
129 if (CheckVirtualKey(VK_DOWN
) || CheckVirtualKey('S')) m_key_S
= 1;
130 if (CheckVirtualKey(VK_LEFT
) || CheckVirtualKey('A')) m_key_A
= 1;
131 if (CheckVirtualKey(VK_RIGHT
) || CheckVirtualKey('D')) m_key_D
= 1;
132 if (m_key_W
) m_key_S
= 0; //forward has priority
133 if (m_key_A
) m_key_D
= 0; //left has priority
136 m_keyrcr_W
|= m_key_W
;
138 m_keyrcr_S
|= m_key_S
;
140 m_keyrcr_A
|= m_key_A
;
142 m_keyrcr_D
|= m_key_D
;
144 if (CheckVirtualKey(VK_RETURN
)) { m_key_SPACE
= 1; }
145 m_keyrcr_SPACE
<<= 1;
146 m_keyrcr_SPACE
|= m_key_SPACE
;
148 if ((m_keyrcr_A
& 3) == 2 || (m_keyrcr_D
& 3) == 2)
150 if ((m_keyrcr_W
& 3) == 2 || (m_keyrcr_S
& 3) == 2)
153 m_LTHUMB
.x
+= -f32(m_key_A
);
154 m_LTHUMB
.x
+= f32(m_key_D
);
155 m_LTHUMB
.y
+= f32(m_key_W
);
156 m_LTHUMB
.y
+= -f32(m_key_S
);
157 m_LTHUMB
.x
= clamp_tpl(m_LTHUMB
.x
, -1.0f
, 1.0f
);
158 m_LTHUMB
.y
= clamp_tpl(m_LTHUMB
.y
, -1.0f
, 1.0f
);
162 //---------------------------------------------------------------------------
164 void CModelViewportCE::PlayerControlHuman(const Vec2
& vViewDir2D
, f32 fGroundRadian
, f32 fGroundRadianMoveDir
)
166 float color1
[4] = { 1, 1, 1, 1 };
167 IRenderAuxGeom
* pAuxGeom
= m_renderer
->GetIRenderAuxGeom();
168 f32 FrameTime
= GetISystem()->GetITimer()->GetFrameTime();
170 ISkeletonAnim
* pISkeletonAnim
= GetCharacterBase()->GetISkeletonAnim();
171 ISkeletonPose
* pISkeletonPose
= GetCharacterBase()->GetISkeletonPose();
173 pISkeletonAnim
->SetAnimationDrivenMotion(1);
174 pISkeletonAnim
->SetLayerPlaybackScale(0, 1); //no scaling
176 //------------------------------------------------------------------------------
177 //------------------------------------------------------------------------------
178 //------------------------------------------------------------------------------
180 if (m_LTHUMB
.GetLength() > 1.0f
)
181 m_LTHUMB
.Normalize();
183 uint32 num
= sizeof(m_arrLTHUMB
) / sizeof(Vec2
);
184 for (int32 i
= (num
- 2); i
> -1; i
--)
185 m_arrLTHUMB
[i
+ 1] = m_arrLTHUMB
[i
];
186 m_arrLTHUMB
[0] = m_LTHUMB
;
188 uint32 index
= 0; //min(uint32(0.10f/m_AverageFrameTime),num-1);
190 f32 fDesiredSpeed
= m_arrLTHUMB
[index
].GetLength() * 5.0f
;
191 if (fDesiredSpeed
> 0.1f
)
193 if (fDesiredSpeed
> 3.0f
)
194 fDesiredSpeed
= 5.0f
;
196 fDesiredSpeed
= 1.3f
;
199 f32 fSlopeSlowDown
= 1.0f
- fabsf(fGroundRadian
);
200 m_renderer
->Draw2dLabel(12, g_ypos
, 1.2f
, color1
, false, "fSlopeSlowDown: %f", fSlopeSlowDown
);
203 static f32 fDesiredSpeedSmooth
= 0;
204 static f32 fDesiredSpeedRate
= 0;
205 SmoothCD(fDesiredSpeedSmooth
, fDesiredSpeedRate
, m_AverageFrameTime
, fDesiredSpeed
, 0.001f
);
207 // uint32 SnapTurn=0;
208 f32 rad
= Ang3::CreateRadZ(m_arrLTHUMB
[index
], m_arrLTHUMB
[0]);
209 /*if ( fabsf(rad)>(gf_PI*0.5f) && m_arrLTHUMB[0].GetLength()>0.85f && m_arrLTHUMB[index].GetLength()>0.80f )
212 //fDesiredSpeed=0.0f;
213 for (int32 i=1; i<num; i++)
214 m_arrLTHUMB[i]=m_arrLTHUMB[0];
215 Vec2 dir = m_arrLTHUMB[0].GetNormalized();
216 m_vWorldDesiredBodyDirection.x = dir.x*vViewDir2D.y+dir.y*vViewDir2D.x;
217 m_vWorldDesiredBodyDirection.y = dir.y*vViewDir2D.y-dir.x*vViewDir2D.x;
220 //use the GamePad radian to set the m_vWorldDesiredBodyDirection
221 m_renderer
->Draw2dLabel(12, g_ypos
, 1.2f
, color1
, false, "vViewDir2D: %f %f RAD:%f ", vViewDir2D
.x
, vViewDir2D
.y
, fabsf(rad
));
223 m_renderer
->Draw2dLabel(12, g_ypos
, 1.2f
, color1
, false, "index: %d", index
);
226 if (fDesiredSpeed
> 0.1f
)
228 Vec2 dir
= m_arrLTHUMB
[index
].GetNormalized();
229 m_vWorldDesiredBodyDirection
.x
= dir
.x
* vViewDir2D
.y
+ dir
.y
* vViewDir2D
.x
;
230 m_vWorldDesiredBodyDirection
.y
= dir
.y
* vViewDir2D
.y
- dir
.x
* vViewDir2D
.x
;
232 m_vWorldDesiredMoveDirection
= m_vWorldDesiredBodyDirection
; //in this case we always travel in the body direction.
234 uint32 LookIK
= m_pCharPanel_Animation
->GetLookIK();
235 IAnimationPoseBlenderDir
* pIPoseBlenderLook
= pISkeletonPose
->GetIPoseBlenderLook();
236 if (pIPoseBlenderLook
)
238 pIPoseBlenderLook
->SetState(LookIK
);
239 pIPoseBlenderLook
->SetFadeoutAngle(DEG2RAD(120));
240 pIPoseBlenderLook
->SetTarget(m_PhysicalLocation
.t
+ m_vWorldDesiredBodyDirection
* 20);
243 uint32 AimIK
= m_pCharPanel_Animation
->GetAimIK();
244 Vec3 vAimPos
= Vec3(12.0f
, +10.0f
, 1.0f
);
245 IAnimationPoseBlenderDir
* pIPoseBlenderAim
= pISkeletonPose
->GetIPoseBlenderAim();
246 if (pIPoseBlenderAim
)
248 pIPoseBlenderAim
->SetState(AimIK
);
249 pIPoseBlenderAim
->SetTarget(vAimPos
);
250 pIPoseBlenderAim
->SetFadeOutSpeed(0.4f
);
252 pAuxGeom
->SetRenderFlags(e_Def3DPublicRenderflags
);
254 static uint32 keyrcr_R
= 0;
255 keyrcr_R
= (keyrcr_R
<< 1) | uint32(m_RT
> 0.8f
);
256 if ((keyrcr_R
& 3) == 1)
257 pISkeletonPose
->ApplyRecoilAnimation(0.2f
, 0.10f
, 1);
259 static Ang3 angle
= Ang3(ZERO
);
263 AABB sAABB
= AABB(Vec3(-0.1f
, -0.1f
, -0.1f
), Vec3(+0.1f
, +0.1f
, +0.1f
));
264 OBB obb
= OBB::CreateOBBfromAABB(Matrix33::CreateRotationXYZ(angle
), sAABB
);
265 pAuxGeom
->DrawOBB(obb
, vAimPos
, 1, RGBA8(0xff, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded
);
267 static f32 fGroundRadianSmooth
= 0;
268 static f32 fGroundRadianRate
= 0;
269 SmoothCD(fGroundRadianSmooth
, fGroundRadianRate
, m_AverageFrameTime
, fGroundRadian
, 0.10f
);
271 static f32 fGroundRadianMoveDirSmooth
= 0;
272 static f32 fGroundRadianMoveDirRate
= 0;
273 SmoothCD(fGroundRadianMoveDirSmooth
, fGroundRadianMoveDirRate
, m_AverageFrameTime
, fGroundRadianMoveDir
, 0.10f
);
276 Vec2 vLTHUMB
= m_arrLTHUMB
[0] * 5.0f
;
277 if (vLTHUMB
.GetLength() > 0.001f
)
279 Vec2 dir
= vLTHUMB
.GetNormalized();
280 m_vWorldDesiredBodyDirection2
.x
= dir
.x
* vViewDir2D
.y
+ dir
.y
* vViewDir2D
.x
;
281 m_vWorldDesiredBodyDirection2
.y
= dir
.y
* vViewDir2D
.y
- dir
.x
* vViewDir2D
.x
;
285 f32 fRadBody
= -atan2f(m_vWorldDesiredBodyDirection2
.x
, m_vWorldDesiredBodyDirection2
.y
);
286 Matrix33 MatBody33
= Matrix33::CreateRotationZ(fRadBody
);
287 const f32 size
= 0.009f
;
288 const f32 length
= 2.2f
;
289 AABB yaabb
= AABB(Vec3(-size
, 0.0f
, -size
), Vec3(size
, length
, size
));
290 OBB obb
= OBB::CreateOBBfromAABB(MatBody33
, yaabb
);
291 pAuxGeom
->DrawOBB(obb
, m_PhysicalLocation
.t
, 1, RGBA8(0x00, 0xff, 0xff, 0x00), eBBD_Extremes_Color_Encoded
);
292 pAuxGeom
->DrawCone(m_PhysicalLocation
.t
+ MatBody33
.GetColumn1() * length
, MatBody33
.GetColumn1(), 0.03f
, 0.15f
, RGBA8(0x00, 0xff, 0xff, 0x00));
297 //------------------------------------------------------------------------
299 //------------------------------------------------------------------------
300 void CModelViewportCE::PlayerControlCamera()
303 m_relCameraRotZ
= m_RTHUMB
.x
* m_AverageFrameTime
;
304 m_relCameraRotX
= m_RTHUMB
.y
* m_AverageFrameTime
;
306 //update and clamp rotation-speed
307 f32 YawRad
= -m_relCameraRotZ
* 2; //yaw-speed
308 m_absLookDirectionXY
= Matrix33::CreateRotationZ(YawRad
) * m_absLookDirectionXY
;
309 m_absLookDirectionXY
.Normalize();
311 m_absCameraHigh
-= m_relCameraRotX
;
312 if (m_absCameraHigh
> 3)
314 if (m_absCameraHigh
< 0)
317 SmoothCD(m_LookAt
, m_LookAtRate
, m_AverageFrameTime
, Vec3(m_PhysicalLocation
.t
.x
, m_PhysicalLocation
.t
.y
, 0.7f
), 0.02f
);
318 // Vec3 dir = (m_absLookDirectionXY+vWorldCurrentBodyDirection).GetNormalizedSafe(Vec3(0,1,0));
319 // m_absCameraPos = -dir*2 + m_LookAt+Vec3(0,0,m_absCameraHigh);
320 m_absCameraPos
= -m_absLookDirectionXY
* 2 + m_LookAt
+ Vec3(0, 0, m_absCameraHigh
);
322 Matrix33 orientation
= Matrix33::CreateRotationVDir((m_LookAt
- m_absCameraPos
).GetNormalized(), 0);
323 if (m_pCharPanel_Animation
->GetFixedCamera())
325 m_absCameraPos
= Vec3(0, 3, 1);
326 orientation
= Matrix33::CreateRotationVDir((m_LookAt
- m_absCameraPos
).GetNormalized());
328 SetViewTM(Matrix34(orientation
, m_absCameraPos
));
331 //---------------------------------------------------------------------------
332 //---------------------------------------------------------------------------
333 //---------------------------------------------------------------------------
335 int PostProcessCallback_PlayControl(ICharacterInstance
* pInstance
, void* pPlayer
)
337 //process bones specific stuff (IK, torso rotation, etc)
338 ((CModelViewportCE
*)pPlayer
)->PostProcessCallback_PlayControl(pInstance
);
341 void CModelViewportCE::PostProcessCallback_PlayControl(ICharacterInstance
* pInstance
)
343 IRenderAuxGeom
* pAuxGeom
= m_renderer
->GetIRenderAuxGeom();
344 ISkeletonAnim
* pISkeletonAnim
= pInstance
->GetISkeletonAnim();
345 //float color1[4] = {1,1,1,1};
346 //m_renderer->Draw2dLabel(12,g_ypos,1.2f,color1,false,"PlayerControl PostprocessCallback" );
348 UseFootIKNew(pInstance
);
351 //-------------------------------------------------------------------------------------------
352 //-------------------------------------------------------------------------------------------
353 //-------------------------------------------------------------------------------------------
354 uint32
CModelViewportCE::UseFootIKNew(ICharacterInstance
* pInstance
)
356 float color1
[4] = { 1, 1, 1, 1 };
357 IRenderAuxGeom
* pAuxGeom
= m_renderer
->GetIRenderAuxGeom();
358 ISkeletonAnim
* pISkeletonAnim
= pInstance
->GetISkeletonAnim();
359 ISkeletonPose
* pISkeletonPose
= pInstance
->GetISkeletonPose();
360 const IDefaultSkeleton
& rIDefaultSkeleton
= pInstance
->GetIDefaultSkeleton();
362 f32 fSmoothTime
= 0.07f
;
364 static Ang3 angle
= Ang3(ZERO
);
368 AABB sAABB
= AABB(Vec3(-0.02f
, -0.02f
, -0.02f
), Vec3(+0.02f
, +0.02f
, +0.02f
));
369 OBB obb
= OBB::CreateOBBfromAABB(Matrix33::CreateRotationXYZ(angle
), sAABB
);
375 m_arrBBoxes
.resize(0);
377 m33
= Matrix33::CreateRotationXYZ(Ang3(-0.5f
, 0, 0));
378 wAABB
= AABB(Vec3(-10.00f
, -10.00f
, -0.10f
), Vec3(+10.00f
, +10.00f
, +0.20f
));
379 bbox
.obb
= OBB::CreateOBBfromAABB(m33
, wAABB
);
380 bbox
.pos
= Vec3(0, -5.0f
, 0);
381 bbox
.col
= RGBA8(0xff, 0x00, 0x00, 0xff);
382 m_arrBBoxes
.push_back(bbox
);
384 m33
= Matrix33::CreateRotationXYZ(Ang3(0, 0, 0));
385 wAABB
= AABB(Vec3(-20.00f
, -20.00f
, -0.50f
), Vec3(+20.00f
, +20.00f
, -0.01f
));
386 bbox
.obb
= OBB::CreateOBBfromAABB(m33
, wAABB
);
387 bbox
.pos
= Vec3(0, -5.0f
, 0);
388 bbox
.col
= RGBA8(0x1f, 0x1f, 0x3f, 0xff);
389 m_arrBBoxes
.push_back(bbox
);
391 m33
= Matrix33::CreateRotationXYZ(Ang3(0, 0, 0));
392 wAABB
= AABB(Vec3(-2.00f
, -2.00f
, -0.20f
), Vec3(+2.00f
, +2.00f
, +0.20f
));
393 bbox
.obb
= OBB::CreateOBBfromAABB(m33
, wAABB
);
394 bbox
.pos
= Vec3(5, 4, 0);
395 bbox
.col
= RGBA8(0x3f, 0x1f, 0x1f, 0xff);
396 m_arrBBoxes
.push_back(bbox
);
398 m33
= Matrix33::CreateRotationXYZ(Ang3(0, 0, 0));
399 wAABB
= AABB(Vec3(-1.00f
, -1.00f
, -0.20f
), Vec3(+1.00f
, +1.00f
, +0.30f
));
400 bbox
.obb
= OBB::CreateOBBfromAABB(m33
, wAABB
);
401 bbox
.pos
= Vec3(5, 4, 0);
402 bbox
.col
= RGBA8(0x3f, 0x1f, 0x1f, 0xff);
403 m_arrBBoxes
.push_back(bbox
);
405 m33
= Matrix33::CreateRotationXYZ(Ang3(0, 0, 0));
406 wAABB
= AABB(Vec3(-1.00f
, -1.00f
, -0.20f
), Vec3(+1.00f
, +1.00f
, +0.20f
));
407 bbox
.obb
= OBB::CreateOBBfromAABB(m33
, wAABB
);
408 bbox
.pos
= Vec3(-5, 7, 0.1f
);
409 bbox
.col
= RGBA8(0x3f, 0x1f, 0x1f, 0xff);
410 m_arrBBoxes
.push_back(bbox
);
412 Vec3 vCharWorldPos
= m_PhysicalLocation
.t
;
413 IVec CWP
= CheckFootIntersection(vCharWorldPos
, vCharWorldPos
);
415 f32 fMinHigh
= m_PhysicalLocation
.t
.z
;
416 if (fMinHigh
< CWP
.heel
.z
)
417 fMinHigh
= CWP
.heel
.z
;
418 Vec3 vGroundNormalRoot
= CWP
.nheel
* m_PhysicalLocation
.q
;
420 f32 fGroundAngle
= acos_tpl(vGroundNormalRoot
.z
);
421 f32 fGroundHeight
= fMinHigh
- (fGroundAngle
* 0.3f
);
422 Vec3 gnormal
= Vec3(0, vGroundNormalRoot
.y
, vGroundNormalRoot
.z
);
423 f32 cosine
= Vec3(0, 0, 1) | gnormal
;
424 Vec3 sine
= Vec3(0, 0, 1) % gnormal
;
425 f32 fGroundAngleMoveDir
= RAD2DEG(atan2(sgn(sine
.x
) * sine
.GetLength(), cosine
));
427 // m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"GroundAngle: rad:%f degree:%f fGroundAngleMoveDir:%f", fGroundAngle, RAD2DEG(fGroundAngle), fGroundAngleMoveDir );
430 //take always the lowest leg for the body position
431 static f32 fGroundHeightSmooth
= 0.0f
;
432 static f32 fGroundHeightRate
= 0.0f
;
433 SmoothCD(fGroundHeightSmooth
, fGroundHeightRate
, m_AverageFrameTime
, fGroundHeight
, fSmoothTime
);
435 // m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"fGroundHeightSmooth: %f", fGroundHeightSmooth );
437 // m_PhysicalLocation.t.z = fGroundHeightSmooth; //stay on ground
439 int32 LHeelIdx
= rIDefaultSkeleton
.GetJointIDByName("Bip01 L Heel");
440 if (LHeelIdx
< 0) return 0;
441 int32 LToe0Idx
= rIDefaultSkeleton
.GetJointIDByName("Bip01 L Toe0");
442 if (LToe0Idx
< 0) return 0;
443 uint32 FootplantL
= 0;
444 Vec3 Final_LHeel
= m_PhysicalLocation
* pISkeletonPose
->GetAbsJointByID(LHeelIdx
).t
;
445 Vec3 Final_LToe0
= m_PhysicalLocation
* pISkeletonPose
->GetAbsJointByID(LToe0Idx
).t
;
447 int32 RHeelIdx
= rIDefaultSkeleton
.GetJointIDByName("Bip01 R Heel");
448 if (RHeelIdx
< 0) return 0;
449 int32 RToe0Idx
= rIDefaultSkeleton
.GetJointIDByName("Bip01 R Toe0");
450 if (RToe0Idx
< 0) return 0;
451 uint32 FootplantR
= 0;
452 Vec3 Final_RHeel
= m_PhysicalLocation
* pISkeletonPose
->GetAbsJointByID(RHeelIdx
).t
;
453 Vec3 Final_RToe0
= m_PhysicalLocation
* pISkeletonPose
->GetAbsJointByID(RToe0Idx
).t
;
455 //-------------------------------------------------------------------------
457 IVec L4
= CheckFootIntersection(Final_LHeel
, Final_LToe0
);
458 pAuxGeom
->DrawOBB(obb
, L4
.toe
, 1, RGBA8(0xff, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded
);
459 pAuxGeom
->DrawOBB(obb
, L4
.heel
, 1, RGBA8(0x1f, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded
);
461 IVec R4
= CheckFootIntersection(Final_RHeel
, Final_RToe0
);
462 pAuxGeom
->DrawOBB(obb
, R4
.toe
, 1, RGBA8(0xff, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded
);
463 pAuxGeom
->DrawOBB(obb
, R4
.heel
, 1, RGBA8(0x1f, 0xff, 0xff, 0xff), eBBD_Extremes_Color_Encoded
);
465 static Plane
LSmoothGroundPlane(Vec3(0, 0, 1), 0);
466 static Plane
LSmoothGroundPlaneRate(Vec3(0, 0, 1), 0);
468 Plane
LGroundPlane(Vec3(0, 0, 1), 0);
469 if ((L4
.heel
.z
- Final_LHeel
.z
) > -0.03f
)
470 LGroundPlane
= Plane::CreatePlane(L4
.nheel
* m_PhysicalLocation
.q
, m_PhysicalLocation
.GetInverted() * L4
.heel
);
471 //m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"LGroundPlane: %f %f %f d:%f", LGroundPlane.n.x,LGroundPlane.n.y,LGroundPlane.n.z,LGroundPlane.d );
474 SmoothCD(LSmoothGroundPlane
, LSmoothGroundPlaneRate
, m_AverageFrameTime
, LGroundPlane
, fSmoothTime
);
475 // m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"LSmoothGroundPlane: %f %f %f d:%f", LSmoothGroundPlane.n.x,LSmoothGroundPlane.n.y,LSmoothGroundPlane.n.z,LSmoothGroundPlane.d );
479 static Plane
RSmoothGroundPlane(Vec3(0, 0, 1), 0);
480 static Plane
RSmoothGroundPlaneRate(Vec3(0, 0, 1), 0);
482 Plane
RGroundPlane(Vec3(0, 0, 1), 0);
483 if ((R4
.heel
.z
- Final_RToe0
.z
) > -0.03f
)
484 RGroundPlane
= Plane::CreatePlane(R4
.nheel
* m_PhysicalLocation
.q
, m_PhysicalLocation
.GetInverted() * R4
.heel
);
485 //m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"RGroundPlane: %f %f %f d:%f", RGroundPlane.n.x,RGroundPlane.n.y,RGroundPlane.n.z,RGroundPlane.d );
488 SmoothCD(RSmoothGroundPlane
, RSmoothGroundPlaneRate
, m_AverageFrameTime
, RGroundPlane
, fSmoothTime
);
489 // m_renderer->Draw2dLabel(12,g_ypos,1.5f,color1,false,"RSmoothGroundPlane: %f %f %f d:%f", RSmoothGroundPlane.n.x,RSmoothGroundPlane.n.y,RSmoothGroundPlane.n.z,RSmoothGroundPlane.d );
496 IVec
CModelViewportCE::CheckFootIntersection(const Vec3
& Final_Heel
, const Vec3
& Final_Toe0
)
498 IRenderAuxGeom
* pAuxGeom
= m_renderer
->GetIRenderAuxGeom();
502 f32 HeightHeel
= -100.0f
;
503 f32 HeightToe0
= -100.0f
;
504 Vec3 normalHeel
= Vec3(0, 0, 1);
505 Vec3 normalToe0
= Vec3(0, 0, 1);
507 Ray RayHeel
= Ray(Final_Heel
+ Vec3(0.0f
, 0.0f
, 5.5f
), Vec3(0, 0, -1.0f
));
508 Ray RayToe0
= Ray(Final_Toe0
+ Vec3(0.0f
, 0.0f
, 5.5f
), Vec3(0, 0, -1.0f
));
509 //pAuxGeom->DrawLine(RayToeN.origin,RGBA8(0xff,0xff,0xff,0x00),RayToeN.origin+RayToeN.direction*10.0f,RGBA8(0x00,0x0,0xff,0x00));
510 //pAuxGeom->DrawLine(RayHeel.origin,RGBA8(0xff,0xff,0xff,0x00),RayHeel.origin+RayHeel.direction*10.0f,RGBA8(0xff,0x0,0x00,0x00));
512 uint32 numBoxes
= m_arrBBoxes
.size();
514 for (uint32 i
= 0; i
< numBoxes
; i
++)
516 OBB obb
= m_arrBBoxes
[i
].obb
;
517 Vec3 pos
= m_arrBBoxes
[i
].pos
;
518 ColorB col
= m_arrBBoxes
[i
].col
;
519 pAuxGeom
->DrawOBB(obb
, pos
, 1, col
, eBBD_Extremes_Color_Encoded
);
521 ival
= Intersect::Ray_OBB(RayHeel
, pos
, obb
, out
);
523 if (HeightHeel
< out
.z
)
526 normalHeel
= obb
.m33
.GetColumn2(); // * m_PhysicalLocation.q;
530 ival
= Intersect::Ray_OBB(RayToe0
, pos
, obb
, out
);
532 if (HeightToe0
< out
.z
)
535 normalToe0
= obb
.m33
.GetColumn2(); // * m_PhysicalLocation.q;
541 retval
.nheel
= normalHeel
.GetNormalized();
542 retval
.ntoe
= normalToe0
.GetNormalized();
543 retval
.heel
= Vec3(Final_Heel
.x
, Final_Heel
.y
, HeightHeel
);
544 retval
.toe
= Vec3(Final_Toe0
.x
, Final_Toe0
.y
, HeightToe0
);