//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, ReserveAndAdd) { FloatArray a; a.reserve(5); a.add(1.0f); a.add(3.3f); a.add(5.5f); ASSERT_EQ(3u, a.size()); ASSERT_TRUE(a.capacity() >= 5); ASSERT_EQ(1.0f, a[0]); ASSERT_EQ(3.3f, a[1]); ASSERT_EQ(5.5f, a[2]); // To test reuse of buffer float* before = a.ptr(); a.reserve(3); ASSERT_TRUE(a.capacity() >= 5); float* after = a.ptr(); // Check that no realloc has been done ASSERT_EQ(before, after); ASSERT_TRUE(a.capacity() >= 5); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, MinMaxFloat) { FloatArray a; // Test empty arrays EXPECT_FLOAT_EQ(std::numeric_limits<float>::max(), a.min()); EXPECT_FLOAT_EQ(std::numeric_limits<float>::min(), a.max()); a.reserve(5); a.add(1.0f); a.add(-3.3f); a.add(123.5f); a.add(999.9f); a.add(-2.3f); float min = a.min(); float max = a.max(); EXPECT_FLOAT_EQ(-3.3f, min); EXPECT_FLOAT_EQ(999.9f, max); size_t minIdx = 0; size_t maxIdx = 0; a.min(&minIdx); a.max(&maxIdx); EXPECT_EQ(1, minIdx); EXPECT_EQ(3, maxIdx); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, SetSizeZero) { FloatArray a; a.reserve(3); a.add(1.0f); a.add(3.3f); a.add(5.5f); float* before = a.ptr(); a.setSizeZero(); float* after = a.ptr(); ASSERT_EQ(before, after); ASSERT_EQ(0u, a.size()); ASSERT_TRUE(3 <= a.capacity()); a.add(1.1f); a.add(3.4f); a.add(5.6f); ASSERT_EQ(3u, a.size()); ASSERT_EQ(1.1f, a[0]); ASSERT_EQ(3.4f, a[1]); ASSERT_EQ(5.6f, a[2]); }
TEST(ArrayDeathTest, IllegalUsageWithSharedData) { float* f = new float[2]; f[0] = 1; f[1] = 2; { FloatArray a; a.setSharedPtr(f, 2); std::vector<float> sv; sv.push_back(1); EXPECT_DEATH(a.assign(&sv[0], 1), "Assertion"); EXPECT_DEATH(a.assign(sv), "Assertion"); EXPECT_DEATH(a.resize(10), "Assertion"); EXPECT_DEATH(a.setPtr(&sv[0], 1), "Assertion"); EXPECT_DEATH(a.reserve(10), "Assertion"); EXPECT_DEATH(a.squeeze(), "Assertion"); #if CVF_ENABLE_TIGHT_ASSERTS == 1 EXPECT_DEATH(a.setSizeZero(), "Assertion"); #endif } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, ExtractElementsFromIndexedArray) { /// source = {2.0, 5.5, 100.0} /// perItemSourceIndices = { 0, 2, 1, 0, 2} /// -> output = {2.0, 100.0, 5.5, 2.0, 100.0} FloatArray source; source.reserve(3); source.add(2.0f); source.add(5.5f); source.add(100.0f); UIntArray indices; indices.reserve(5); indices.add(0); indices.add(2); indices.add(1); indices.add(0); indices.add(2); ref<FloatArray> arr = source.extractElements(indices); ASSERT_EQ(5, arr->size()); EXPECT_FLOAT_EQ( 2.0, arr->get(0)); EXPECT_FLOAT_EQ(100.0, arr->get(1)); EXPECT_FLOAT_EQ( 5.5, arr->get(2)); EXPECT_FLOAT_EQ( 2.0, arr->get(3)); EXPECT_FLOAT_EQ(100.0, arr->get(4)); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, SqueezeEmptyArray) { FloatArray a; a.reserve(5); ASSERT_EQ(0, a.size()); ASSERT_TRUE(5 <= a.capacity()); a.squeeze(); ASSERT_EQ(0, a.size()); ASSERT_EQ(0, a.capacity()); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, Squeeze) { FloatArray a; a.reserve(5); a.add(1.0f); a.add(3.3f); a.add(5.5f); ASSERT_EQ(3u, a.size()); ASSERT_TRUE(5 <= a.capacity()); a.squeeze(); ASSERT_EQ(3u, a.size()); ASSERT_EQ(3u, a.capacity()); ASSERT_EQ(1.0f, a[0]); ASSERT_EQ(3.3f, a[1]); ASSERT_EQ(5.5f, a[2]); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ArrayTest, ReserveGrow) { FloatArray a; a.resize(3); a.set(0, 1.0f); a.set(1, 3.3f); a.set(2, 5.5f); float* before = a.ptr(); a.reserve(8); float* after = a.ptr(); a.add(2.2f); a.add(2.5f); ASSERT_NE(before, after); ASSERT_EQ(5u, a.size()); ASSERT_TRUE(a.capacity() >= 8); ASSERT_EQ(1.0f, a[0]); ASSERT_EQ(3.3f, a[1]); ASSERT_EQ(5.5f, a[2]); ASSERT_EQ(2.2f, a[3]); ASSERT_EQ(2.5f, a[4]); }
Array* Array_readLocalData(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Object* obj = fr.getObjectForUniqueID(fr[1].getStr()); if (obj) { fr+=2; return dynamic_cast<Array*>(obj); } } osg::notify(osg::WARN)<<"Warning: invalid uniqueID found in file."<<std::endl; return NULL; } std::string uniqueID; if (fr[0].matchWord("UniqueID") && fr[1].isString()) { uniqueID = fr[1].getStr(); fr += 2; } int entry = fr[0].getNoNestedBrackets(); const char* arrayName = fr[0].getStr(); unsigned int capacity = 0; fr[1].getUInt(capacity); ++fr; fr += 2; Array* return_array = 0; if (strcmp(arrayName,"ByteArray")==0) { ByteArray* array = new ByteArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"ShortArray")==0) { ShortArray* array = new ShortArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"IntArray")==0) { IntArray* array = new IntArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UByteArray")==0) { UByteArray* array = new UByteArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UShortArray")==0) { UShortArray* array = new UShortArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UIntArray")==0) { UIntArray* array = new UIntArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UVec4bArray")==0 || strcmp(arrayName,"Vec4ubArray")==0) { Vec4ubArray* array = new Vec4ubArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b,a; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b) && fr[3].getUInt(a)) { fr+=4; array->push_back(osg::Vec4ub(r,g,b,a)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"FloatArray")==0) { FloatArray* array = new FloatArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { float float_value; if (fr[0].getFloat(float_value)) { ++fr; array->push_back(float_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"DoubleArray")==0) { DoubleArray* array = new DoubleArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { double double_value; if (fr[0].getFloat(double_value)) { ++fr; array->push_back(double_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec2Array")==0) { Vec2Array* array = new Vec2Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec2 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())) { fr += 2; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec2dArray")==0) { Vec2dArray* array = new Vec2dArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec2d v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())) { fr += 2; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec3Array")==0) { Vec3Array* array = new Vec3Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec3 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) { fr += 3; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec3dArray")==0) { Vec3dArray* array = new Vec3dArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec3d v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) { fr += 3; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec4Array")==0) { Vec4Array* array = new Vec4Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec4 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w())) { fr += 4; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec4dArray")==0) { Vec4dArray* array = new Vec4dArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec4d v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w())) { fr += 4; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec2bArray")==0) { Vec2bArray* array = new Vec2bArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g; if (fr[0].getUInt(r) && fr[1].getUInt(g)) { fr+=2; array->push_back(osg::Vec2b(r,g)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec3bArray")==0) { Vec3bArray* array = new Vec3bArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b)) { fr+=3; array->push_back(osg::Vec3b(r,g,b)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec4bArray")==0) { Vec4bArray* array = new Vec4bArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b,a; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b) && fr[3].getUInt(a)) { fr+=4; array->push_back(osg::Vec4b(r,g,b,a)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec2sArray")==0) { Vec2sArray* array = new Vec2sArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g; if (fr[0].getUInt(r) && fr[1].getUInt(g)) { fr+=2; array->push_back(osg::Vec2s(r,g)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec3sArray")==0) { Vec3sArray* array = new Vec3sArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b)) { fr+=3; array->push_back(osg::Vec3s(r,g,b)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec4sArray")==0) { Vec4sArray* array = new Vec4sArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b,a; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b) && fr[3].getUInt(a)) { fr+=4; array->push_back(osg::Vec4s(r,g,b,a)); } else ++fr; } ++fr; return_array = array; } if (return_array) { if (!uniqueID.empty()) fr.registerUniqueIDForObject(uniqueID.c_str(),return_array); } return return_array; }
void DoAnim() { static double time = 0.0; //Total time running. static double artTime = 0.0; //Total time with the current art. static DWORD lastTime = 0; //Time of last call. const double elapsed = double(GetTickCount() - lastTime) / 1000.0; if (lastTime) { lastTime = GetTickCount(); } else { lastTime = GetTickCount(); return; } time += elapsed; artTime += elapsed; //If we need new art, get it. static CKnot::AutoArt threads; static Arrays arrays; static FloatArray grid; if (!threads.get() || artTime > ResetTime) { CKnot::StrokeList sl = CreateSquareStrokes(); sl = RemoveStrokes(sl); threads = CKnot::CreateThread(sl); artTime = 0.0; grid.clear(); grid.reserve(sl.size() * 10); for (CKnot::StrokeList::const_iterator it = sl.begin(); it != sl.end(); ++it) { grid.push_back(it->a.x); grid.push_back(it->a.y); grid.push_back(it->type == CKnot::Cross ? 1.0 : 0.0); grid.push_back(it->type == CKnot::Glance ? 1.0 : 0.0); grid.push_back(it->type == CKnot::Bounce ? 1.0 : 0.0); grid.push_back(it->b.x); grid.push_back(it->b.y); grid.push_back(it->type == CKnot::Cross ? 1.0 : 0.0); grid.push_back(it->type == CKnot::Glance ? 1.0 : 0.0); grid.push_back(it->type == CKnot::Bounce ? 1.0 : 0.0); } for (size_t i = 0; i < arrays.size(); ++i) delete arrays[i]; arrays.clear(); const size_t threadCount = threads->GetThreadCount(); for (size_t i = 0; i < threadCount; ++i) { const CKnot::Art::Thread* thread = threads->GetThread(i); const CKnot::Art::Z* z = threads->GetZ(i); const size_t segsPerKnot = 25; const size_t kc = thread->GetKnotCount(); FloatArray* quads = new FloatArray; arrays.push_back(quads); const size_t target = kc * segsPerKnot; const size_t memSize = 12 * (target + 1); quads->reserve(memSize); const float scr = double(rand()) / RAND_MAX / 2; const float ecr = double(rand()) / RAND_MAX / 2 + .5; const float scg = double(rand()) / RAND_MAX / 2; const float ecg = double(rand()) / RAND_MAX / 2 + .5; const float scb = double(rand()) / RAND_MAX / 2; const float ecb = double(rand()) / RAND_MAX / 2 + .5; for (size_t i = 0; i <= target; ++i) { const double s = double(i) / double(target); const double t = s; const CKnot::vec2 cur = thread->Y(t); const CKnot::vec2 dcur = thread->Y(t + .00001); const CKnot::vec2 diff = dcur - cur; CKnot::vec2 normal(diff.y, -diff.x); normal = normal * (1.0 / normal.GetLength()); normal = normal * .01; const CKnot::vec2 flip(-normal.x, -normal.y); const CKnot::vec2 start = cur + normal; const CKnot::vec2 end = cur + flip; const bool over = z->Y(t) > 0.0; //Coords quads->push_back(start.x); quads->push_back(start.y); quads->push_back(over ? 0.01 : .1); //Colors quads->push_back(scr); quads->push_back(scg); quads->push_back(scb); quads->push_back(end.x); quads->push_back(end.y); quads->push_back(over ? 0.01 : .1); quads->push_back(ecr); quads->push_back(ecg); quads->push_back(ecb); } assert(quads->size() == memSize); } } //Clear the background some nice color. glClearColor( 0.125f + std::sin(time / 2.0) / 8.0, 0.125f + std::sin(time / 3.0) / 8.0, 0.125f + std::sin(time / 5.0) / 8.0, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); for (size_t i = 0; i < arrays.size(); ++i) { FloatArray& quads = *arrays[i]; glVertexPointer(3, GL_FLOAT, 24, &quads.front()); glColorPointer(3, GL_FLOAT, 24, &quads.front() + 3); const size_t count = quads.size() / 6; const size_t progress = size_t(std::min(artTime / DrawTime, 1.0) * count / 2); //From 0 to .5 of vertices. assert(progress >= 0); assert(progress <= count / 2); size_t start = (count / 2) - progress; start += start % 2; glDrawArrays(GL_QUAD_STRIP, start, progress * 2); } //Draw graph if (DrawGraph) { glVertexPointer(2, GL_FLOAT, 20, &grid.front()); glColorPointer(3, GL_FLOAT, 20, &grid.front() + 2); glDrawArrays(GL_LINES, 0, grid.size() / 5); } glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glLoadIdentity(); }