/* Draw object functioln. * ARGUMENTS: * - context of the window: * HDC hDC; * - the size of the window: * INT W, H; * RETURNS: None. */ VOID ObjDraw( HDC hDC, INT X, INT Y, DWORD Color, PK2ANIM *Ani ) { INT i; DBL x = sin(30); srand(30); for (i = 0; i < ObjNumOfV; i++) { if (!Ani->IsPause) ObjV[i] = VecMulMatr3(ObjV[i], MatrMulMatr(MatrRotateY(sin(Ani->Time * 0.5)), MatrRotateX(sin(Ani->Time * 3)))); else ObjV[i] = VecMulMatr3(ObjV[i], MatrIdentity()); SetDCBrushColor(hDC, Color); Ellipse(hDC,X + ObjV[i].X - 4, Y - ObjV[i].Y - 4, X + ObjV[i].X + 4, Y - ObjV[i].Y + 4); } } /* End of 'ObjDraw' function */
/* ‘ункци¤ загрузки геометрического объекта из G3D файла. * ј–√”ћ≈Ќ“џ: * - указатель на геометрический объект: * am1GEOM *G; * - им¤ файла: * CHAR *FileName; * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈: * (BOOL) TRUE при успехе, иначе - FALSE. */ BOOL AM1_GeomLoad( am1GEOM *G, CHAR *FileName ) { FILE *F; INT i, j, n; CHAR Sign[4]; MATR M; static CHAR MtlName[300]; static CHAR path_buffer[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; _splitpath(FileName, drive, dir, fname, ext); memset(G, 0, sizeof(am1GEOM)); if ((F = fopen(FileName, "rb")) == NULL) return FALSE; M = MatrTranspose(MatrInverse(AM1_RndPrimMatrConvert)); /* читаем сигнатуру */ fread(Sign, 1, 4, F); if (*(DWORD *)Sign != *(DWORD *)"G3D") { fclose(F); return FALSE; } /* читаем количество примитивов в объекте */ fread(&n, 4, 1, F); fread(MtlName, 1, 300, F); /* читаем и загружаем библиотеку материалов */ _makepath(path_buffer, drive, dir, MtlName, ""); AM1_MtlLoad(path_buffer); /* читаем примитивы */ for (i = 0; i < n; i++) { INT nv, ni, *Ind; am1VERTEX *Vert; am1PRIM P; /* читаем количество вершин и индексов */ fread(&nv, 4, 1, F); fread(&ni, 4, 1, F); /* читаем им¤ материала текущего примитива */ fread(MtlName, 1, 300, F); /* выдел¤ем пам¤ть под вершины и индексы */ if ((Vert = malloc(sizeof(am1VERTEX) * nv + sizeof(INT) * ni)) == NULL) break; Ind = (INT *)(Vert + nv); /* читаем данные */ fread(Vert, sizeof(am1VERTEX), nv, F); /* конвертируем геометрию */ for (j = 0; j < nv; j++) { Vert[j].P = VecMulMatr(Vert[j].P, AM1_RndPrimMatrConvert); Vert[j].N = VecMulMatr3(Vert[j].N, M); } fread(Ind, sizeof(INT), ni, F); /* заносим в примитив */ AM1_PrimCreate(&P, AM1_PRIM_TRIMESH, nv, ni, Vert, Ind); P.MtlNo = AM1_MtlFind(MtlName); free(Vert); /* добавл¤ем примитив к объекту */ AM1_GeomAddPrim(G, &P); } fclose(F); AM1_RndPrimMatrConvert = MatrIdentity(); return TRUE; } /* End of 'AM1_GeomDraw' 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 */