/* Camera move by Right-Axes function. * ARGUMENTS: * - Distance to move: * DBL Coef; * RETURNS: None. */ VOID II2_RndCameraMoveRight( ii2CAMERA *Cam, DBL Coef ) { Cam->Dir = VecSubVec(Cam->At, Cam->Loc); Cam->Right = VecCrossVec(Cam->Dir, Cam->Up); Cam->Loc = VecAddVec(Cam->Loc, VecMulNum(VecNormalize(Cam->Right), Coef)); Cam->At = VecAddVec(Cam->At, VecMulNum(VecNormalize(Cam->Right), Coef)); } /* End of 'II2_RndCameraMoveByDir' funciton */
/* Camera rotation by camera-axes-dir function. * ARGUMENTS: * - Angle: * DBL Angle; * RETURNS: None. */ VOID II2_RndCameraRotateDir( ii2CAMERA *Cam, DBL Angle ) { MATR RotMat; Cam->Dir = VecSubVec(Cam->At, Cam->Loc); Cam->Right = VecCrossVec(VecNormalize(Cam->Dir), Cam->Up); II2_RndCameraNormalize(Cam); RotMat = II2_RndCameraGetMatrix(Cam); RotMat = MatrMulMatr(MatrRotateX(Angle), RotMat); Cam->At = VecAddVec(Cam->Loc, VecSet(RotMat.A[0][0], RotMat.A[0][1], RotMat.A[0][2])); } /* End of 'II2_RndCameraRotateDir' funciton */
/* Функция обновления межкадровых параметров объекта анимации. * АРГУМЕНТЫ: * - указатель на "себя" - сам объект анимации: * ao5UNIT_CTRL *Uni; * - указатель на контекст анимации: * ao5ANIM *Ani; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ static VOID AO5_AnimUnitResponse( ao5UNIT_CTRL *Uni, ao5ANIM *Ani ) { VEC Move, Dir, At; if (Ani->Keys[VK_ESCAPE]) AO5_AnimDoExit(); if (Ani->KeysClick['F']) AO5_AnimFlipFullScreen(); if (Ani->KeysClick['P']) AO5_AnimSetPause(!Ani->IsPause); /* позиционирование корабля */ //Uni->Omega = -3000 * Ani->JX * Ani->DeltaTime; //Uni->Head += -3 * 30 * Ani->JR * Ani->DeltaTime; Dir = VectorTransform(VecSet(0, 0, 1), MatrRotateY(Uni->Head)); //Uni->V += -3 * Ani->JY * Ani->DeltaTime; //Uni->V *= max(1 - Ani->GlobalDeltaTime, 0); if(Ani->Keys['D']) Uni->Head -= 1; if(Ani->Keys['A']) Uni->Head += 1; if(Ani->Keys['W']) Uni->V = -5; else if(Ani->Keys['S']) Uni->V = 5; else Uni->V = 0; Uni->Pos = VecAddVec(Uni->Pos, VecMulNum(Dir, Uni->V * Ani->DeltaTime)); Uni->Pos = VecAddVec(Uni->Pos, VecMulNum(VectorTransform(Dir, MatrRotateY(-90)), Uni->V)); //Uni->Pos.Y += 30 * (Ani->JButs[1] - Ani->JButs[2]) * Ani->DeltaTime; Uni->At = VecSubVec(Uni->Pos, VecMulNum(Dir, 100)); Uni->At.Y += 10; Move = VecSubVec(Uni->At, Uni->CPos); Uni->CPos = VecAddVec(Uni->CPos, VecMulNum(Move, Ani->DeltaTime)); AO5_RndMatrView = MatrView(Uni->CPos, Uni->Pos, VecSet(0, 1, 0)); AO5_RndMatrWorld = MatrMulMatr(MatrMulMatr(MatrRotateY(Uni->Head), MatrTranslate(Uni->Pos.X, Uni->Pos.Y, Uni->Pos.Z)), MatrScale(0.1, 0.1, 0.1)); } /* End of 'AO5_AnimUnitResponse' function */
/* Camera rotation by camera-axes-dir function. * ARGUMENTS: * - Angle: * DBL Angle; * RETURNS: None. */ VOID RK2_RndCameraRotateDir( rk2CAMERA *Cam, DBL Angle ) { rk2MATR4x4 RotMat; Cam->Dir = VecSubVec(Cam->At, Cam->Loc); Cam->Right = VecCrossVec(VecNormalize(Cam->Dir), Cam->Up); RK2_RndCameraNormalize(Cam); RotMat = RK2_RndCameraGetMatrix(Cam); RotMat = MatrMultMatr(MatrRotateX(MatrDefault(), Angle), RotMat); RK2_RndCameraSet(Cam, Cam->Loc, /* Location */ VecSumVec(Cam->Loc, VecSet(RotMat.A[0][0], RotMat.A[0][1], RotMat.A[0][2])), /* At */ Cam->Up); /* Up */ } /* End of 'RK2_RndCameraRotateDir' funciton */
MATR MatrViewLookAt( VEC Loc, VEC At, VEC UpApprox ) { VEC Right, Up, Dir; MATR r; Dir = VecNormalize(VecSubVec(At, Loc)); Right = VecNormalize(VecCrossVec(Dir, UpApprox)); Up = VecCrossVec(Right, Dir); r.A[0][0] = Right.x; r.A[0][1] = Up.x; r.A[0][2] = -Dir.x; r.A[0][3] = 0; r.A[1][0] = Right.y; r.A[1][1] = Up.y; r.A[1][2] = -Dir.y; r.A[1][3] = 0; r.A[2][0] = Right.z; r.A[2][1] = Up.z; r.A[2][2] = -Dir.z; r.A[2][3] = 0; r.A[3][0] = -VecDotVec(Loc, Right); r.A[3][1] = -VecDotVec(Loc, Up); r.A[3][2] = VecDotVec(Loc, Dir); r.A[3][3] = 1; return r; }
static VOID MP2_UnitResponse( mp2CONTROL *Uni, mp2ANIM *Ani ) { DBL r; VEC Dir = VecNormalize(VecSubVec(View, Uni->Pos)), Right = VecNormalize(VecCrossVec(Dir, VecSet(0, 1, 0))); if (Ani->Keys['T']) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (Ani->Keys['Y']) glPolygonMode(GL_FRONT, GL_LINE); if (Ani->Keys['U']) glPolygonMode(GL_BACK, GL_LINE); /*if (Ani->Keys[VK_SPACE]) MP2_AnimAddUnit(MP2_UnitCreateBall()); */ if (Ani->KeysClick['C']) MP2_AnimAddUnit(MP2_UnitCreateCube(/*Rnd1() * 4, Rnd1() * 4, Rnd1() * 4*/0, 0, 0)); if (Ani->KeysClick['V']) MP2_AnimAddUnit(MP2_UnitCreateSTATICMODEL(/*Rnd1() * 4, Rnd1() * 4, Rnd1() * 4*/0, 0, 0)); if (Ani->KeysClick[VK_RETURN] && Ani->Keys[VK_MENU]) MP2_FlipFullScreen(MP2_Anim.hWnd); /*if (Ani->KeysClick[VK_ESCAPE]) MP2_AnimDoExit();*/ if (Ani->KeysClick['P']) Ani->IsPause = !Ani->IsPause; /* Uni->Pos.Y += Ani->JY * Ani->GlobalDeltaTime; */ Uni->Pos = PointTransform(Uni->Pos, MatrRotate((50 * Ani->JY * Ani->GlobalDeltaTime), Right)); Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->JX * Ani->GlobalDeltaTime)); if (Ani->Keys[VK_LBUTTON]) { Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->Mdx * Ani->GlobalDeltaTime)); Uni->Pos = PointTransform(Uni->Pos, MatrRotateX(10 * Ani->Mdy * Ani->GlobalDeltaTime)); } View.X += Ani->JZ / 10; View.Z += Ani->JR / 10; Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(10 * Ani->Keys[VK_RIGHT] * Ani->GlobalDeltaTime)); Uni->Pos = PointTransform(Uni->Pos, MatrRotateY(-10 * Ani->Keys[VK_LEFT] * Ani->GlobalDeltaTime)); r = VecLen(Uni->Pos); Uni->Pos = VecMulNum(Uni->Pos, (r + (-Ani->Mdz) * Ani->DeltaTime * 1.0) / r); MP2_RndMatrView = MatrView(VecAddVec(Uni->Pos, View), View, VecSet(0, 1, 0)); }
/* ‘ункци¤ преобразовани¤ из мировой системы коорлинат в кадр. * ј–√”ћ≈Ќ“џ: * - исходна¤ точка: * VEC Loc, VEC At, VEC Upaprox; * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈: * (MATR) ћатрица преоброзаваний камеры. */ MATR II2_VieverCamera( VEC Loc, VEC At, VEC Upaprox ) { VEC Right, Up, Dir; MATR r; Dir = VecNormalize(VecSubVec(At, Loc)); Right = VecNormalize(VecCrossVec(Dir, Upaprox)); Up = VecCrossVec(Right, Dir); r.A[0][0] = Right.X; r.A[0][1] = Up.X; r.A[0][2] = -Dir.X; r.A[0][3] = 0; r.A[1][0] = Right.Y; r.A[1][1] = Up.Y; r.A[1][2] = -Dir.Y; r.A[1][3] = 0; r.A[2][0] = Right.Z; r.A[2][1] = Up.Z; r.A[2][2] = -Dir.Z; r.A[2][3] = 0; r.A[3][0] = -VecDotVec(Loc, Right); r.A[3][1] = -VecDotVec(Loc, Up); r.A[3][2] = VecDotVec(Loc, Dir); r.A[3][3] = 1; /*r.A[0][0] = Right.X; r.A[1][0] = Up.X; r.A[2][0] = -Dir.X; r.A[3][0] = 0; r.A[0][1] = Right.Y; r.A[1][1] = Up.Y; r.A[2][1] = -Dir.Y; r.A[3][1] = 0; r.A[0][2] = Right.Z; r.A[1][2] = Up.Z; r.A[2][2] = -Dir.Z; r.A[3][2] = 0; r.A[0][3] = -VecDotVec(Loc, Right); r.A[1][3] = -VecDotVec(Loc, Up); r.A[2][3] = -VecDotVec(Loc, Dir); r.A[3][3] = 1;*/ return r; } /* End of 'Ani->WorldToScreen' function */
/* Camera move by Dir-axes properties * ARGUMENTS: * - Distance to move: * DBL Coef; * RETURNS: None. */ VOID II2_RndCameraMoveDir( ii2CAMERA *Cam, DBL Coef ) { Cam->Dir = VecNormalize(VecSubVec(Cam->At, Cam->Loc)); Cam->Loc = VecAddVec(Cam->Loc, VecMulNum(Cam->Dir, Coef)); Cam->At = VecAddVec(Cam->At, VecMulNum(Cam->Dir, Coef)); } /* End of 'II2_RndCameraMoveByDir' funciton */
/* Camera move by Dir-axes properties * ARGUMENTS: * - Distance to move: * DBL Coef; * RETURNS: None. */ VOID RK2_RndCameraMoveDir( rk2CAMERA *Cam, DBL Coef ) { Cam->Dir = VecNormalize(VecSubVec(Cam->At, Cam->Loc)); Cam->Loc = VecSumVec(Cam->Loc, VecMultNum(Cam->Dir, Coef)); Cam->At = VecSumVec(Cam->At, VecMultNum(Cam->Dir, Coef)); } /* End of 'RK2_RndCameraMoveByDir' funciton */
/* Helpful triangle normal evaluation function. * ARGUMENTS: * - triangle points: * VEC P0, P1, P2; * RETURNS: * (VEC) normal vector value. */ static VEC AK2_TriangleNormal( VEC P0, VEC P1, VEC P2 ) { return VecNormalize(VecCrossVec(VecSubVec(P1, P0), VecSubVec(P2, P0))); } /* End of 'AK2_TriangleNormal' function */
/* Функция обновления межкадровых параметров объекта анимации. * АРГУМЕНТЫ: * - указатель на "себя" - сам объект анимации: * vg4UNIT_CTRL *Uni; * - указатель на контекст анимации: * vg4ANIM *Ani; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ static VOID VG4_AnimUnitResponse( vg4UNIT_CTRL *Uni, vg4ANIM *Ani ) { VEC Dir, Move; static FLT y = -0.067452297, z = 2.6340842; static DBL time = 5; time += VG4_Anim.GlobalDeltaTime; if (time > 5) { time = 0; VG4_ShaderFree(Uni->Axes.ProgId); VG4_ShaderFree(Uni->Helic.ProgId); Uni->Helic.ProgId = VG4_ShaderLoad("HELIC"); Uni->Axes.ProgId = VG4_ShaderLoad("AXIS"); Uni->Sph.ProgId = Uni->Axes.ProgId; } /* позиционирование вертолета */ Uni->Omega = -3000 * Ani->JR * Ani->DeltaTime; Uni->Head += -3 * 30 * Ani->JR * Ani->DeltaTime; Dir = VecMulMatr3(VecSet(0, 0, 1), MatrRotateY(Uni->Head)); Uni->V += -30 * Ani->JY * Ani->DeltaTime; Uni->V *= max(1 - Ani->GlobalDeltaTime, 0); Uni->Pos = VecAddVec(Uni->Pos, VecMulNum(Dir, Uni->V * Ani->DeltaTime)); Uni->Pos = VecAddVec(Uni->Pos, VecMulNum(VecMulMatr3(Dir, MatrRotateY(-90)), 30 * Ani->JX * Ani->DeltaTime)); Uni->Pos.Y += 30 * (Ani->JButs[1] - Ani->JButs[2]) * Ani->DeltaTime; /* точка "интереса" */ Uni->At = VecSubVec(Uni->Pos, VecMulNum(Dir, 9)); Uni->At.Y += 5.30; Move = VecSubVec(Uni->At, Uni->CPos); Uni->CPos = VecAddVec(Uni->CPos, VecMulNum(Move, Ani->DeltaTime)); VG4_RndMatrView = MatrView(Uni->CPos, Uni->Pos, VecSet(0, 1, 0)); if (Ani->KeysClick['W']) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (Ani->KeysClick['Q']) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (Ani->Keys[VK_ESCAPE]) VG4_AnimDoExit(); if (Ani->KeysClick['F']) VG4_AnimFlipFullScreen(); if (Ani->KeysClick['P']) VG4_AnimSetPause(!Ani->IsPause); /* анимация вертолета */ Uni->Helic.Prims[2].M = MatrRotateY(999 * Ani->Time); Uni->Helic.Prims[4].M = MatrMulMatr(MatrMulMatr(MatrTranslate(0, y, z), MatrRotateX(888 * Ani->Time)), MatrTranslate(0, -y, -z)); y += Ani->Keys[VK_ADD] * Ani->GlobalDeltaTime * 0.1 - Ani->Keys[VK_SUBTRACT] * Ani->GlobalDeltaTime * 0.1; z += Ani->Keys['A'] * Ani->GlobalDeltaTime * 0.1 - Ani->Keys['Z'] * Ani->GlobalDeltaTime * 0.1; } /* End of 'VG4_AnimUnitResponse' function */