bool Scene::Process3DTap(int action, const grinliz::Vector2F& view, const grinliz::Ray& world, Engine* engine) { Ray ray; bool result = false; switch( action ) { case GAME_PAN_START: { game->GetScreenport().ViewProjectionInverse3D( &dragData3D.mvpi ); engine->RayFromViewToYPlane( view, dragData3D.mvpi, &ray, &dragData3D.start3D ); dragData3D.startCameraWC = engine->camera.PosWC(); dragData3D.end3D = dragData3D.start3D; dragData3D.start2D = dragData3D.end2D = view; threeDTapDown = true; break; } case GAME_PAN_MOVE: case GAME_PAN_END: { // Not sure how this happens. Why is the check for down needed?? if( threeDTapDown ) { Vector3F drag; engine->RayFromViewToYPlane( view, dragData3D.mvpi, &ray, &drag ); dragData3D.end2D = view; Vector3F delta = drag - dragData3D.start3D; GLASSERT( fabsf( delta.x ) < 1000.f && fabsf( delta.y ) < 1000.0f ); delta.y = 0; drag.y = 0; dragData3D.end3D = drag; if ( action == GAME_TAP_UP ) { threeDTapDown = false; Vector2F vDelta = dragData3D.start2D - dragData3D.end2D; if ( vDelta.Length() < 10.f ) result = true; } engine->camera.SetPosWC(dragData3D.startCameraWC - delta); } break; } } return result; }
//---------------------------------------------------------------------------- Texture2D* Sample5::CreateTexture() { if (mspTexture) { return mspTexture; } // define the properties of the image to be used as a texture const UInt width = 256; const UInt height = 256; const Image2D::FormatMode format = Image2D::FM_RGB888; const UInt bpp = Image2D::GetBytesPerPixel(format); ColorRGB* const pColorDst = WIRE_NEW ColorRGB[width*height]; // create points with random x,y position and color TArray<Cell> cells; Random random; for (UInt i = 0; i < 10; i++) { Cell cell; cell.point.X() = random.GetFloat() * width; cell.point.Y() = random.GetFloat() * height; cell.color.R() = random.GetFloat(); cell.color.G() = random.GetFloat(); cell.color.B() = random.GetFloat(); Float max = 0.0F; max = max < cell.color.R() ? cell.color.R() : max; max = max < cell.color.G() ? cell.color.G() : max; max = max < cell.color.B() ? cell.color.B() : max; max = 1.0F / max; cell.color *= max; cells.Append(cell); } // iterate over all texels and use the distance to the 2 closest random // points to calculate the texel's color Float max = 0; for (UInt y = 0; y < height; y++) { for (UInt x = 0; x < width; x++) { Float minDist = MathF::MAX_REAL; Float min2Dist = MathF::MAX_REAL; UInt minIndex = 0; for (UInt i = 0; i < cells.GetQuantity(); i++) { Vector2F pos(static_cast<Float>(x), static_cast<Float>(y)); // Handle tiling Vector2F vec = cells[i].point - pos; vec.X() = MathF::FAbs(vec.X()); vec.Y() = MathF::FAbs(vec.Y()); vec.X() = vec.X() > width/2 ? width-vec.X() : vec.X(); vec.Y() = vec.Y() > height/2 ? height-vec.Y() : vec.Y(); Float distance = vec.Length(); if (minDist > distance) { min2Dist = minDist; minDist = distance; minIndex = i; } else if (min2Dist > distance) { min2Dist = distance; } } Float factor = (min2Dist - minDist) + 3; ColorRGB color = cells[minIndex].color * factor; pColorDst[y*width+x] = color; max = max < color.R() ? color.R() : max; max = max < color.G() ? color.G() : max; max = max < color.B() ? color.B() : max; } } // convert and normalize the ColorRGBA float array to an 8-bit per // channel texture max = 255.0F / max; UChar* const pDst = WIRE_NEW UChar[width * height * bpp]; for (UInt i = 0; i < width*height; i++) { ColorRGB color = pColorDst[i]; pDst[i*bpp] = static_cast<UChar>(color.R() * max); pDst[i*bpp+1] = static_cast<UChar>(color.G() * max); pDst[i*bpp+2] = static_cast<UChar>(color.B() * max); } Image2D* pImage = WIRE_NEW Image2D(format, width, height, pDst); Texture2D* pTexture = WIRE_NEW Texture2D(pImage); // The texture tiles are supposed to be seamless, therefore // we need the UV set to be repeating. pTexture->SetWrapType(0, Texture2D::WT_REPEAT); pTexture->SetWrapType(1, Texture2D::WT_REPEAT); // save the texture for later reference mspTexture = pTexture; return pTexture; }