void CTimeSystem::ApplyTimeEnv() { ColorSet(m_material.diffuse, 1.0f, 1.0f, 1.0f, 1.0f); ColorSet(m_material.ambient, 0.5f, 0.5f, 0.5f, 1.0f); m_D3DRender->SetLight( 0 , &m_light ); m_D3DRender->SetMaterial( &m_material ); }
CTimeSystem::CTimeSystem() { ColorSet( m_material.diffuse , 1.0f , 1.0f , 1.0f , 1.0f ); ColorSet( m_material.ambient , 0.5f , 0.5f , 0.5f , 1.0f ); ColorSet( m_material.specular , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_material.emissive , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_light.diffuse , 1.0f , 1.0f , 1.0f , 1.0f ); ColorSet( m_light.ambient , 0.5f , 0.5f , 0.5f , 1.0f ); ColorSet( m_light.specular , 0.0f , 0.0f , 0.0f , 0.0f ); m_brightness = 0.5f; m_gamma = 1.0f; m_contrast = 0.7f; SetTimeStateEnv( TIME_DAY ); m_fogColor = 0x00000000; m_pRainDropper = NULL; m_pSnowDropper = NULL; }
static const std::vector<ColorSet> possibilities() { std::vector<ColorSet> p; p.push_back(ColorSet(0, 0, 0)); p.push_back(ColorSet(0, 0, 1)); p.push_back(ColorSet(0, 1, 0)); p.push_back(ColorSet(0, 1, 1)); p.push_back(ColorSet(1, 0, 0)); p.push_back(ColorSet(1, 0, 1)); p.push_back(ColorSet(1, 1, 0)); p.push_back(ColorSet(1, 1, 1)); return p; }
/* Функция инициализации объекта анимации. * АРГУМЕНТЫ: * - указатель на "себя" - сам объект анимации: * vg4UNIT_CTRL *Uni; * - указатель на контекст анимации: * vg4ANIM *Ani; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ static VOID VG4_AnimUnitInit( vg4UNIT_CTRL *Uni, vg4ANIM *Ani ) { vg4PRIM pr; Uni->hFnt = CreateFont(30, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, "Bookman Old Style"); VG4_RndPrimMatrConvert = MatrMulMatr(MatrMulMatr(MatrScale(0.0024, 0.0024, 0.0024), MatrRotateX(-0)), MatrTranslate(0, 0, 0)); VG4_GeomLoad(&Uni->Helic, "MODELS\\Mi8\\havoc.g3d"); Uni->Helic.ProgId = VG4_ShaderLoad("HELIC"); VG4_RndPrimDefaultColor = ColorSet(1, 0, 0, 1); VG4_PrimCreatePlane(&pr, VecSet(-500, -0.030, 0), VecSet(1000, 0, 0), VecSet(0, 0.059, 0), 2, 2); VG4_GeomAddPrim(&Uni->Axes, &pr); VG4_RndPrimDefaultColor = ColorSet(0, 0, 1, 1); VG4_PrimCreatePlane(&pr, VecSet(0, -0.030, -500), VecSet(0, 0, 1000), VecSet(0, 0.059, 0), 2, 2); VG4_GeomAddPrim(&Uni->Axes, &pr); VG4_RndPrimDefaultColor = ColorSet(0, 1, 0, 1); VG4_PrimCreatePlane(&pr, VecSet(-0.030, -500, 0), VecSet(0, 1000, 0), VecSet(0.059, 0, 0), 2, 2); VG4_GeomAddPrim(&Uni->Axes, &pr); Uni->Axes.ProgId = VG4_ShaderLoad("AXIS"); VG4_RndPrimDefaultColor = ColorSet(0.7, 0.5, 0.3, 1); VG4_PrimCreateSphere(&Uni->Sph, VecSet(0, 0, 0), 1, 8, 15); Uni->Sph.ProgId = Uni->Axes.ProgId; /* начальные параметры вертолета */ Uni->Pos = VecSet(0, 18, 0); Uni->V = 0; Uni->Head = 0; Uni->Omega = 0; Uni->CPos = VecSet(59, 30, 59); } /* End of 'VG4_AnimUnitInit' function */
// Update the Fade Pattern void FadeUpdate() { // Calculate linear interpolation between Color1 and Color2 // Optimise order of operations to minimize truncation error uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps; uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps; uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps; uint8_t white = ((White(Color1) * (TotalSteps - Index)) + (White(Color2) * Index)) / TotalSteps; // Serial.print(red); Serial.print(","); // Serial.print(green); Serial.print(","); // Serial.print(blue); Serial.print(","); // Serial.print(white); Serial.println(); ColorSet(Color(red, green, blue, white)); show(); Increment(); }
/*! @brief 直接照明計算 @param[o] out: 出力輝度 @param[i] v: 着目点 @param[i] mtrl: マテリアル */ void Renderer::DirectLighting(Color& out, const Ray& ray, const Vertex& v, const Material& mtrl) { // 自己遮蔽で引っかかるため法線方向に押し出す const float epsilon = 0.001f; Ray to_lig; ColorSet(&out, 0.0f, 0.0f, 0.0f); const LightList& list = scene->GetLightList(); for(LightList::const_iterator it = list.begin(); it != list.end(); it++) { // occlusion test #ifdef USE_OCCLUSION_TEST if((*it)->type == Light::Type_Point) { Vec3Subtract(&to_lig.dir, &(*it)->pos, &v.p); float d = sqrtf(Vec3InnerProduct(&to_lig.dir, &to_lig.dir)); if(d < FLT_EPSILON) continue; Vec3Scale(&to_lig.dir, &to_lig.dir, 1.0f/d); Vec3Scale(&to_lig.org, &to_lig.dir, epsilon); Vec3Add(&to_lig.org, &v.p, &to_lig.org); float t; if(FindOccluder(t, to_lig) && (t <= (d + epsilon))) continue; } else { to_lig.dir = -(*it)->dir; Vec3Scale(&to_lig.org, &to_lig.dir, epsilon); Vec3Add(&to_lig.org, &v.p, &to_lig.org); float t; if(FindOccluder(t, to_lig)) continue; } #endif // USE_OCCLUSION_TEST // lighting Color col; (*it)->Lighting(col, ray, v, mtrl); ColorAdd3(&out, &out, &col); } }
/*! @brief 間接照明計算 @param[o] out: 出力輝度 @param[i] v: 着目点 @param[i] mtrl: マテリアル @param[i] depth: 深度 */ void Renderer::IndirectLighting(Color& out, const Ray& ray, const Vertex& v, const Material& mtrl, std::size_t depth) { ColorSet(&out, 0.0f, 0.0f, 0.0f); const float e = (float)genrand_real1(); if(e < mtrl.kd) { Ray ray2; // 2nd ray ray2.org = v.p; random_vector_cosweight(&ray2.dir, &v.n); Color ref; Trace(ref, ray2, depth+1); // out += (brdf * ref * cosθ) / (pdf * kd) Color temp; ColorModulate3(&temp, &mtrl.pd, &ref); ColorScale3(&out, &temp, 1.0f / mtrl.kd); } else if(e < (mtrl.kd + mtrl.ks)) { // Vector3 in = -ray.dir; Ray ray2; ray2.org = v.p; random_vector_cosweight(&ray2.dir, &in, &v.n, mtrl.shine); float cost= Vec3InnerProduct(&ray2.dir, &v.n); if(cost <= 0.0f) return; Color ref; Trace(ref, ray2, depth+1); // out += (brdf * ref * cosθ) / (pdf * ks) Color temp; ColorScale3(&temp, &mtrl.ps, (mtrl.shine + 2.0f)/(mtrl.shine + 1.0f) * cost); ColorScale3(&out, &temp, 1.0f / mtrl.ks); } }
/*! @brief 描画メイン @param[i] bx: 開始座標 @param[i] by: 開始座標 @param[i] ex: 終了座標 @param[i] yx: 終了座標 */ void Renderer::Render(std::size_t bx, std::size_t by, std::size_t ex, std::size_t ey) { FrameBufferFP32& fb = camera->GetFrameBuffer(); const std::size_t w = fb.width(); const std::size_t h = fb.height(); const float inv_w = 1.0f / (float)w; const float inv_h = 1.0f / (float)h; const std::size_t smapling = max_sampling; Ray ray; ray.org = camera->GetPosture().row_vector3(3); Color col, accum; for(std::size_t y = by; y < ey; y++) { FrameBufferFP32::Data* p = fb.ptr(y) + bx; for(std::size_t x = bx; x < ex; x++) { ColorSet(&accum, 0.0f, 0.0f, 0.0f); for(std::size_t s = 0; s < smapling; s++) { const float sub_x = ((float)x + ((float)genrand_real1() - 0.5f)) * inv_w; const float sub_y = ((float)y + ((float)genrand_real1() - 0.5f)) * inv_h; camera->ShootRay(ray, sub_x, sub_y); Trace(col, ray, 0); ColorAdd3(&accum, &accum, &col); } ColorScale3(&col, &accum, 1.0f/(float)smapling); p->ch[0] = col.r; p->ch[1] = col.g; p->ch[2] = col.b; p++; } } }
int Command(AlienFxHandle_t *fx, char **cmdv) { int cmdc = CommandCount(cmdv); // cmdv[cmdc] == (char*)0 if(debug) fprintf(stderr, "command %s with cmdc %d\n", *cmdv, cmdc); if( ! strcmp("color", cmdv[0])) { if(cmdc < 4) { fputs("error: too few arguments to command \"color\"\n", stderr); return 0; } else { int block = BLOCK_AC_POWER; // int block = BLOCK_LOAD_ON_BOOT char *all[] = { "all", 0 }; unsigned int region = LightMask(fx, all); int r = 0, g = 0, b = 0; if( (1 == sscanf(cmdv[1], "%d", &r)) && (1 == sscanf(cmdv[2], "%d", &g)) && (1 == sscanf(cmdv[3], "%d", &b))) { if(cmdc > 4) region = LightMask(fx, & cmdv[4]); if(debug) fprintf(stderr, "command: color %d %d %d %x\n", r,g,b, region); Reset(fx->usb_handle, RESET_ALL_LIGHTS_ON); /* apparently some types may need a brief pause here */ usleep(fx->info->post_reset_delay); ColorSet(fx->usb_handle, block, region, r, g, b); Loop(fx->usb_handle); SendAndExec(fx->usb_handle); } } } else if( ! strcmp("info", cmdv[0])) { if(verbose) { printf(" idVendor %#6x \n", fx->info->idVendor); printf(" idProduct %#6x %s\n", fx->info->idProduct, fx->info->name); } unsigned int i; unsigned int primitives = 0; unsigned int composites = 0; for(i = 0 ; i < fx->info->lightsCount ; ++i) if(fx->info->lights[i].is_composite) ++composites; else ++primitives; printf(" light primitives %d\n", primitives); printf(" light composites %d\n", composites); printf(" region type name\n"); printf(" ------ --------- ----\n"); for(i = 0 ; i < fx->info->lightsCount ; ++i) printf(" %#6x %s %s\n", fx->info->lights[i].id, fx->info->lights[i].is_composite ? "composite" : "primitive", fx->info->lights[i].name); if(debug) { struct libusb_device *usb_dev = 0; struct libusb_device_descriptor usb_desc; if( (usb_dev = libusb_get_device(fx->usb_handle)) && (0 == libusb_get_device_descriptor(usb_dev, & usb_desc))) { printf(" bLength %d\n", usb_desc.bLength); printf(" bDescriptorType %d\n", usb_desc.bDescriptorType); printf(" bcdUSB %d\n", usb_desc.bcdUSB); printf(" bDeviceClass %d\n", usb_desc.bDeviceClass); printf(" bDeviceSubClass %d\n", usb_desc.bDeviceSubClass); printf(" bDeviceProtocol %d\n", usb_desc.bDeviceProtocol); printf(" bMaxPacketSize0 %d\n", usb_desc.bMaxPacketSize0); printf(" idVendor %#x\n", usb_desc.idVendor); printf(" idProduct %#x\n", usb_desc.idProduct); printf(" bcdDevice %d\n", usb_desc.bcdDevice); printf(" iManufacturer %#x\n", usb_desc.iManufacturer); printf(" iProduct %#x\n", usb_desc.iProduct); printf(" iSerialNumber %#x\n", usb_desc.iSerialNumber); printf(" bNumConfigurations %d\n", usb_desc.bNumConfigurations); } } } else { fprintf(stderr, "unrecognized command \"%s\"\n", cmdv[0]); Syntax(stderr); } return 1; }
int ColorSetAll(libusb_device_handle *alienfx, int block, int r, int g, int b) { return ColorSet(alienfx, block, 0xffffff, r, g, b); }
void CTimeSystem::SetLightAmbientParam( vec4_t ambient ) { ColorSet( m_light.ambient , ambient[0] , ambient[1] , ambient[2] , ambient[3] ); }
void CTimeSystem::SetTimeStateEnv( TIMESTATE state ) { m_light.type = DIRECTIONAL_LIGHT; VectorCopy( m_light.position , m_lightPos ); VectorCopy( m_light.direction , m_lightDir ); m_light.range = 1000.0f; m_light.falloff = 1.0f; m_light.attenuation0 = 0.0f; m_light.attenuation1 = 1.0f; m_light.attenuation2 = 0.0f; m_light.phi = 0.0f; m_light.theta = 0.0f; m_timeState = state; if ( state == TIME_DAY ) { } else if( state == TIME_DAWN ) { ColorSet( m_material.diffuse , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.ambient , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.specular , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.emissive , 0.0f , 0.0f , 0.0f , 0.0f ); m_material.power = 32.0f; ColorSet( m_light.diffuse , 180.0f / 255.0f , 196.0f / 255.0f , 90.0f / 255.0f , 0.0f ); ColorSet( m_light.ambient , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_light.specular , 0.0f , 0.0f , 0.0f , 0.0f ); m_staticColor = 0xffb4c45a; m_dynamicColor = 0xffb4c45a; m_fogColor = 0xffe4f48a; m_fogStart = 6000.0f; m_fogEnd = 10000.0f; } else if( state == TIME_DUSK ){ ColorSet( m_material.diffuse , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.ambient , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.specular , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.emissive , 0.0f , 0.0f , 0.0f , 0.0f ); m_material.power = 32.0f; ColorSet( m_light.diffuse , 196.0f / 255.0f , 121.0f / 255.0f , 66.0f / 255.0f , 0.0f ); ColorSet( m_light.ambient , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_light.specular , 0.0f , 0.0f , 0.0f , 0.0f ); m_staticColor = 0xffc47942; m_dynamicColor = 0xffc47942; m_fogColor = 0xffc47942; m_fogStart = 1000.0f; m_fogEnd = 10000.0f; } else if( state == TIME_NIGHT ){ ColorSet( m_material.diffuse , 0.6f , 0.6f , 0.6f , 0.0f ); ColorSet( m_material.ambient , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.specular , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.emissive , 0.0f , 0.0f , 0.0f , 0.0f ); m_material.power = 32.0f; ColorSet( m_light.diffuse , 51.0f / 255.0f , 51.0f / 255.0f , 51.0f / 255.0f , 0.0f ); ColorSet( m_light.ambient , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_light.specular , 0.0f , 0.0f , 0.0f , 0.0f ); m_staticColor = 0xff333333; m_dynamicColor = 0xff333333; m_fogColor = 0xff444444; m_fogStart = 6000.0f; m_fogEnd = 10000.0f; } else if( state == TIME_FOG ){ ColorSet( m_material.diffuse , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.ambient , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.specular , 0.4f , 0.4f , 0.4f , 0.0f ); ColorSet( m_material.emissive , 0.0f , 0.0f , 0.0f , 0.0f ); m_material.power = 32.0f; ColorSet( m_light.diffuse , 133.0f / 255.0f , 133.0f / 255.0f , 207.0f / 255.0f , 0.0f ); ColorSet( m_light.ambient , 0.0f , 0.0f , 0.0f , 0.0f ); ColorSet( m_light.specular , 0.0f , 0.0f , 0.0f , 0.0f ); m_staticColor = 0xff8585cf; m_dynamicColor = 0xff8585cf; m_fogColor = 0xffb5b5ff; m_fogStart = 1000.0f; m_fogEnd = 10000.0f; } }
/* Функция загрузки геометрического объекта. * АРГУМЕНТЫ: * - геометрический объект: * as4GEOM *G; * - имя файла материалов: * CHAR *FileName; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: * (BOOL) TRUE при успехе. */ BOOL AS4_GeomLoad( as4GEOM *G, CHAR *FileName ) { INT vn = 0, vtn = 0, vnn = 0, fn = 0, pn = 0, size, i, p; FILE *F; /* читаемые данные */ VEC *ReadV, *ReadN; as4UV *ReadUV; INT (*ReadF)[3]; /* хранение примитивов */ struct { INT First, Last, /* первый и последний номера вершин примитива */ Mtl; /* материал примитива */ } *PrimInfo; memset(G, 0, sizeof(as4GEOM)); /* разбиваем имя на части и открываем файл */ _splitpath(FileName, ModelDrive, ModelDir, ModelFileName, ModelFileExt); if ((F = fopen(FileName, "rt")) == NULL) return FALSE; /* считаем количества */ while (fgets(Buf, sizeof(Buf), F) != NULL) if (Buf[0] == 'v' && Buf[1] == ' ') vn++; else if (Buf[0] == 'v' && Buf[1] == 't') vtn++; else if (Buf[0] == 'v' && Buf[1] == 'n') vnn++; else if (Buf[0] == 'f' && Buf[1] == ' ') fn += Split() - 3; else if (strncmp(Buf, "usemtl", 6) == 0) pn++; if (pn == 0) pn = 1; /* материалы не использовались */ /* загружаем: * вершины vn * нормали vvn * текстурные координаты vtn * треугольники fn * примитивы pn * дополнительно: * индексы (Vv, Vn, Vt) <- новые номера вершин ? (vn + vt + vnn) * ??? * начальные индексы vn */ /* выделяем память под вспомогательные данные */ size = sizeof(VEC) * vn + /* вершины vn */ sizeof(VEC) * vnn + /* нормали vnn */ sizeof(as4UV) * vtn + /* текстурные координаты vtn */ sizeof(INT [3]) * fn + /* треугольники fn */ sizeof(PrimInfo[0]) * pn + /* примитивы pn */ sizeof(VertexRefs[0]) * (vn + vtn + vnn) + /* индексы (Vv, Vn, Vt) (vn + vt + vnn) */ sizeof(INT) * vn; /* начальные индексы vn */ if ((ReadV = malloc(size)) == NULL) { fclose(F); return FALSE; } memset(ReadV, 0, size); /* расставляем указатели */ ReadN = ReadV + vn; ReadUV = (as4UV *)(ReadN + vnn); ReadF = (INT (*)[3])(ReadUV + vtn); VertexRefsStart = (INT *)(ReadF + fn); PrimInfo = (VOID *)(VertexRefsStart + vn); VertexRefs = (VOID *)(PrimInfo + pn); NumOfAllocedVertexRefs = vn + vtn + vnn; NumOfVertexRefs = 0; /* начала списка индексов вершин ==> -1 */ memset(VertexRefsStart, 0xFF, sizeof(INT) * vn); memset(VertexRefs, 0xFF, sizeof(VertexRefs[0]) * NumOfAllocedVertexRefs); /* второй проход - читаем геометрию */ rewind(F); vn = 0; vtn = 0; vnn = 0; fn = 0; pn = 0; PrimInfo[0].First = 0; /* считаем количества */ while (fgets(Buf, sizeof(Buf), F) != NULL) if (Buf[0] == 'v' && Buf[1] == ' ') { FLT x = 0, y = 0, z = 0; sscanf(Buf + 2, "%f%f%f", &x, &y, &z); ReadV[vn++] = VecSet(x, y, z); } else if (Buf[0] == 'v' && Buf[1] == 't') { FLT u = 0, v = 0; sscanf(Buf + 3, "%f%f", &u, &v); ReadUV[vtn++] = AS4_UVSet(u, v); } else if (Buf[0] == 'v' && Buf[1] == 'n') { FLT nx = 0, ny = 0, nz = 0; sscanf(Buf + 3, "%f%f%f", &nx, &ny, &nz); ReadN[vnn++] = VecNormalize(VecSet(nx, ny, nz)); } else if (Buf[0] == 'f' && Buf[1] == ' ') { INT n0[3], n1[3], n[3], r0, r1, r; Split(); SCANF3(Parts[1], n0); r0 = GetVertexNo(n0[0], n0[1], n0[2]); SCANF3(Parts[2], n1); r1 = GetVertexNo(n1[0], n1[1], n1[2]); for (i = 3; i < NumOfParts; i++) { SCANF3(Parts[i], n); r = GetVertexNo(n[0], n[1], n[2]); ReadF[fn][0] = r0; ReadF[fn][1] = r1; ReadF[fn][2] = r; r1 = r; fn++; } } else if (strncmp(Buf, "usemtl", 6) == 0) { Split(); /* запоминаем номер последней грани */ if (pn != 0) PrimInfo[pn - 1].Last = fn - 1; /* ищем материал */ for (i = 0; i < G->NumOfMtls; i++) if (strcmp(Parts[1], G->Mtls[i].Name) == 0) break; if (i == G->NumOfMtls) PrimInfo[pn].Mtl = -1; else PrimInfo[pn].Mtl = i; PrimInfo[pn].First = fn; pn++; } else if (strncmp(Buf, "mtllib ", 7) == 0) { Split(); LoadMaterials(G, Parts[1]); } /* у последнего примитива запоминаем номер последней грани */ if (pn == 0) { PrimInfo[0].Last = fn - 1; PrimInfo[0].Mtl = -1; } else PrimInfo[pn - 1].Last = fn - 1; fclose(F); /* Формируем примитивы из прочитанных данных */ AS4_DefaultColor = ColorSet(1, 1, 1); for (p = 0; p < pn; p++) { INT minv, maxv, j; as4PRIM prim; BOOL is_need_normal = FALSE; minv = maxv = ReadF[PrimInfo[p].First][0]; for (i = PrimInfo[p].First; i <= PrimInfo[p].Last; i++) for (j = 0; j < 3; j++) { if (minv > ReadF[i][j]) minv = ReadF[i][j]; if (maxv < ReadF[i][j]) maxv = ReadF[i][j]; } vn = maxv - minv + 1; fn = PrimInfo[p].Last - PrimInfo[p].First + 1; AS4_PrimCreate(&prim, AS4_PRIM_TRIMESH, vn, fn * 3); /* копируем вершины */ for (i = 0; i < vn; i++) { INT n; prim.V[i].P = ReadV[VertexRefs[minv + i].Nv]; if ((n = VertexRefs[minv + i].Nn) != -1) prim.V[i].N = ReadN[n]; else is_need_normal = TRUE; if ((n = VertexRefs[minv + i].Nt) != -1) prim.V[i].T = ReadUV[n]; } /* копируем грани */ for (i = 0; i < fn; i++) for (j = 0; j < 3; j++) prim.I[i * 3 + j] = ReadF[PrimInfo[p].First + i][j] - minv; if (is_need_normal) AS4_PrimAutoNormals(&prim); prim.Mtl = PrimInfo[p].Mtl; AS4_GeomAddPrim(G, &prim); } /* освобождаем память из-под прочитанных данных */ free(ReadV); return TRUE; } /* End of 'AS4_GeomLoad' function */
ColorSet best_counter() { return ColorSet(!b, a, b); }