/* ‘ункци¤ преобразовани¤ вершин. * ј–√”ћ≈Ќ“џ: * - геометрический объект: * ap6GEOM *G; * - матрица преобразовани¤: * MATR M; * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈: Ќет. */ VOID AP6_GeomTransform( ap6GEOM *G, MATR M ) { INT i, j; MATR InvM = MatrTranspose(MatrInverse(M)); InvM.A[3][0] = InvM.A[3][1] = InvM.A[3][2] = 0; for (i = 0; i < G->NumOfPrims; i++) for (j = 0; j < G->Prims[i].NumOfV; j++) { G->Prims[i].V[j].P = VecMulMatr(G->Prims[i].V[j].P, M); G->Prims[i].V[j].N = VecMulMatr(G->Prims[i].V[j].N, InvM); } } /* End of 'AP6_GeomTransform' function */
/* Primitive draw function. * ARGUMENTS: * - primtive to draw: * vg4PRIM *Pr; * RETURNS: None. */ VOID VG4_RndPrimDraw( vg4PRIM *Pr ) { INT i; MATR M; POINT *pts; /* Build transform matrix */ M = MatrMulMatr(VG4_RndMatrWorld, MatrMulMatr(VG4_RndMatrView, VG4_RndMatrProj)); /* Transform all points */ pts = malloc(sizeof(POINT) * Pr->NumOfP); if (pts == NULL) return; for (i = 0; i < Pr->NumOfP; i++) { /* NDC */ VEC p = VecMulMatr(Pr->P[i], M); pts[i].x = (p.X + 1) * VG4_Anim.W / 2; pts[i].y = (-p.Y + 1) * VG4_Anim.H / 2; } /* Draw all lines */ for (i = 0; i < Pr->NumOfE; i++) { INT n0 = Pr->Edges[i][0], n1 = Pr->Edges[i][1]; MoveToEx(VG4_Anim.hDC, pts[n0].x, pts[n0].y, NULL); LineTo(VG4_Anim.hDC, pts[n1].x, pts[n1].y); } free(pts); } /* End of 'VG4_RndPrimDraw' function */
/* Функция построения объекта анимации. * АРГУМЕНТЫ: * - указатель на "себя" - сам объект анимации: * od6UNIT_COW *Unit; * - указатель на контекст анимации: * od6ANIM *Ani; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ static VOID CowUnitRender( od6UNIT_COW *Unit, od6ANIM *Ani ) { INT i, N = 0; VEC p = {1, 0, 0}; POINT pt; static DBL Delta = 0.1; Delta += Ani->JZ * Ani->GlobalDeltaTime; OD6_RndMatrView = MatrViewLookAt(VecMulMatr(VecSet(0, 0, Ani->JX * Delta + 15), MatrRotateX(90 * Ani->JY)), VecSet(0, 0, 0), VecSet(0, 1, 0)); OD6_RndMatrWorld = MatrRotateZ(-Ani->Time); OD6_RndMatrWorld = MatrMulMatr(OD6_RndMatrWorld, MatrScale(0.30, 0.30, 0.30)); SetDCBrushColor(Ani->hDC, RGB(255, 255, 255)); SetDCPenColor(Ani->hDC, RGB(255, 255, 255)); srand(30); for (i = 0; i < N; i++) { p.X = 2.0 * rand() / RAND_MAX - 1 ; p.Y = 2.0 * rand() / RAND_MAX - 1 ; p.Z = 2.0 * rand() / RAND_MAX - 1 ; pt = OD6_RndWorldToScreen(p); if (i == 0) MoveToEx(Ani->hDC, pt.x , pt.y, NULL); else LineTo(Ani->hDC, pt.x , pt.y); } OD6_RndGObjDraw(&Unit->Cow, Ani->hDC); /* OD6_RndMatrWorld = MatrRotateZ(-Ani->GlobalTime / 60); OD6_RndMatrWorld = MatrMulMatr(OD6_RndMatrWorld, MatrScale(0.30, 0.30, 0.30)); SetDCBrushColor(Ani->hDC, RGB(0, 255, 255)); SetDCPenColor(Ani->hDC, RGB(0, 255, 255)); OD6_RndGObjDraw(&Unit->Cow, Ani->hDC); OD6_RndMatrWorld = MatrRotateZ(-Ani->GlobalTime / 60 / 60); OD6_RndMatrWorld = MatrMulMatr(OD6_RndMatrWorld, MatrScale(0.30, 0.30, 0.30)); SetDCBrushColor(Ani->hDC, RGB(255, 255, 0)); SetDCPenColor(Ani->hDC, RGB(255, 255, 0)); OD6_RndGObjDraw(&Unit->Cow, Ani->hDC); OD6_RndMatrWorld = MatrRotateY(Ani->Time * 30); OD6_RndMatrWorld = MatrMulMatr(OD6_RndMatrWorld, MatrScale(0.30, 0.30, 0.30)); OD6_RndMatrWorld = MatrMulMatr(MatrTranslate(0.0, 0.0, 3 * 3.30), OD6_RndMatrWorld); OD6_RndGObjDraw(&Unit->Cow, Ani->hDC); */ } /* End of 'CowUnitRender' function */
mtl.Ka = VecSet(0.1, 0.1, 0.1); mtl.Kd = VecSet(1, 1, 1); mtl.Ks = VecSet(0, 0, 0); mtl.Phong = 30; mtl.Trans = 1; mtl.TexNo = 0; mtl.MapD[0] = 0; strcpy(mtl.MapD, "map2-hf.bmp"); strcpy(mtl.Name, "Height Field Material"); prim.Mtl = VG4_GeomAddMaterial(&Unit->Obj, &mtl); VG4_GeomAddPrim(&Unit->Obj, &prim); . . . Ani->MatrWorld = MatrIdentity(); Ani->MatrView = MatrViewLookAt( VecMulMatr(VecMulMatr(VecSet(25, 25, 25), MatrRotateY(Ani->JR * 180)), MatrRotateZ(Ani->JY * 180)), VecSet(0, 0, 0), VecSet(0, 1, 0)); WVP = MatrMulMatr(VG4_Anim.MatrWorld, MatrMulMatr(VG4_Anim.MatrView, VG4_Anim.MatrProjection)); glLoadMatrixf(WVP.A[0]); . . . Ani->MatrWorld = MatrMulMatr(MatrRotateX(-0), MatrTranslate(0, 0, 0.30 * sin(Ani->Time))); VG4_GeomDraw(&Unit->Obj);
/* ‘ункци¤ загрузки геометрического объекта из 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 */