void ShapeTest::firstCollision() { Scene3D scene; ShapeGroup3D shapes; Object3D a(&scene); Shape<Shapes::Sphere3D> aShape(a, {{1.0f, -2.0f, 3.0f}, 1.5f}, &shapes); Object3D b(&scene); Shape<Shapes::Point3D> bShape(b, {{3.0f, -2.0f, 3.0f}}, &shapes); Object3D c(&scene); Shape<Shapes::Composition3D> cShape(c, &shapes); /* No collisions initially */ CORRADE_VERIFY(!shapes.firstCollision(aShape)); CORRADE_VERIFY(!shapes.firstCollision(bShape)); CORRADE_VERIFY(!shapes.isDirty()); /* Move point into sphere */ b.translate(Vector3::xAxis(-1.0f)); /* Collision */ CORRADE_VERIFY(shapes.isDirty()); CORRADE_VERIFY(shapes.firstCollision(aShape) == &bShape); CORRADE_VERIFY(shapes.firstCollision(bShape) == &aShape); CORRADE_VERIFY(!shapes.isDirty()); }
void Convolve(CImageOf<T> src, CImageOf<T>& dst, CFloatImage kernel, float scale, float offset) { // Determine the shape of the kernel and row buffer CShape kShape = kernel.Shape(); CShape sShape = src.Shape(); CShape bShape(sShape.width + kShape.width, kShape.height, sShape.nBands); int bWidth = bShape.width * bShape.nBands; // Allocate the result, if necessary, and the row buffer dst.ReAllocate(sShape, false); CFloatImage buffer(bShape); if (sShape.width * sShape.height * sShape.nBands == 0) return; CFloatImage output(CShape(sShape.width, 1, sShape.nBands)); // Fill up the row buffer initially for (int k = 0; k < kShape.height; k++) FillRowBuffer(&buffer.Pixel(0, k, 0), src, kernel, k, bWidth); // Determine if clipping is required // (we assume up-conversion to float never requires clipping, i.e., // floats have the highest dynamic range) T minVal = dst.MinVal(); T maxVal = dst.MaxVal(); if (minVal <= buffer.MinVal() && maxVal >= buffer.MaxVal()) minVal = maxVal = 0; // Process each row for (int y = 0; y < sShape.height; y++) { // Do the convolution ConvolveRow2D(buffer, kernel, &output.Pixel(0, 0, 0), sShape.width); // Scale, offset, and type convert ScaleAndOffsetLine(&output.Pixel(0, 0, 0), &dst.Pixel(0, y, 0), sShape.width * sShape.nBands, scale, offset, minVal, maxVal); // Shift up the row buffer and fill the last line if (y < sShape.height-1) { int k; for (k = 0; k < kShape.height-1; k++) memcpy(&buffer.Pixel(0, k, 0), &buffer.Pixel(0, k+1, 0), bWidth * sizeof(float)); FillRowBuffer(&buffer.Pixel(0, k, 0), src, kernel, y+k+1, bWidth); } } }
void ShapeTest::collision() { Scene3D scene; ShapeGroup3D shapes; Object3D a(&scene); Shape<Shapes::Sphere3D> aShape(a, {{1.0f, -2.0f, 3.0f}, 1.5f}, &shapes); { /* Collision with point inside the sphere */ Shape<Shapes::Point3D> aShape2(a, {{1.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); const Collision3D collision = aShape.collision(aShape2); CORRADE_VERIFY(collision); CORRADE_COMPARE(collision.position(), Vector3(1.0f, -2.0f, 3.0f)); } { /* No collision with point inside the sphere, but not in the same group */ ShapeGroup3D shapes2; Shape<Shapes::Point3D> aShape3(a, {{1.0f, -2.0f, 3.0f}}, &shapes2); shapes2.setClean(); CORRADE_VERIFY(!aShape.collision(aShape3)); } { CORRADE_EXPECT_FAIL("Should cross-scene collision work or not?"); /* No collision with point inside the sphere, but not in the same scene */ Scene3D scene2; Object3D c(&scene2); Shape<Shapes::Point3D> cShape(c, {{1.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); CORRADE_VERIFY(!aShape.collision(cShape)); } { /* No collision with point outside of the sphere */ Object3D b(&scene); Shape<Shapes::Point3D> bShape(b, {{3.0f, -2.0f, 3.0f}}, &shapes); shapes.setClean(); CORRADE_VERIFY(!aShape.collision(bShape)); /* Move point inside the sphere -- collision */ b.translate(Vector3::xAxis(-1.0f)); shapes.setClean(); const Collision3D collision = aShape.collision(bShape); CORRADE_VERIFY(collision); CORRADE_COMPARE(collision.position(), Vector3(2.0f, -2.0f, 3.0f)); } }