/*! Init curve with curve points and times. If no control points are passed they will be calculated automatically @param points Array of points on the Bézier curve (w = time) @param controlPoints Array of control points with size = 2*(numPointsAndTimes-1) */ void SLCurveBezier::init(const SLVVec4f& points, const SLVVec3f& controlPoints) { assert(points.size() > 1); dispose(); // set up arrays _points.clear(); _points.resize(points.size()); _controls.resize(2*(points.size()-1)); // copy interpolated data SLuint i; for (i = 0; i < _points.size(); ++i) { _points[i] = points[i]; } if (controlPoints.size()==0) { if (points.size() > 2) { // create approximating control points for (i = 0; i < _points.size()-1; ++i) { if (i > 0) _controls[2*i] = (_points[i] + (_points[i+1]-_points[i-1])/3.0f).vec3(); if (i < _points.size()-2) _controls[2*i+1] = (_points[i+1] - (_points[i+2]-_points[i ])/3.0f).vec3(); } _controls[0] = (SLVec4f(_controls[1]) - (_points[1] - _points[0])/3.0f).vec3(); _controls[2*_points.size()-3] = (SLVec4f(_controls[2*_points.size()-4]) + (_points[_points.size()-1] - _points[_points.size()-2])/3.0f).vec3(); } else { _controls[0] = (_points[0] + (_points[1]-_points[0])/3.0f).vec3(); _controls[1] = (_points[1] - (_points[1]-_points[0])/3.0f).vec3(); } } else { // copy approximating control points for (i = 0; i < 2*(_points.size()-1); ++i) _controls[i] = controlPoints[i]; } // set up curve segment lengths _lengths.clear(); _lengths.resize(_points.size()-1); _totalLength = 0.0f; _totalLength = 0.0f; for (SLuint i = 0; i < _points.size()-1; ++i) { _lengths[i] = segmentArcLength(i, 0.0f, 1.0f); _totalLength += _lengths[i]; } }
//----------------------------------------------------------------------------- TurnTableGameScene::TurnTableGameScene(SkeletonData* defaultSkeletonData, SLint localPlayerIndex, SLint maxPlayers, SLMat4f* playerPositions, VR_MODEL* models) : GameScene(defaultSkeletonData, localPlayerIndex, maxPlayers, playerPositions, models) { _matTable = new SLMaterial[3]; _matTable[0].name("matTableLeg"); _matTable[0].ambient(SLVec4f(0.0f, 0.0f, 0.0f, 1.0f)); _matTable[0].diffuse(SLVec4f(0.0f, 0.0f, 0.0f, 1.0f)); _matTable[1].name("matTablePlate"); _matTable[1].ambient(SLVec4f(1.0f, 1.0f, 1.0f, 0.6f)); _matTable[1].diffuse(SLVec4f(1.0f, 1.0f, 1.0f, 0.6f)); _matTable[2].name("matTestBox"); _matTable[2].ambient(SLVec4f(1.0f, 0.5f, 0.0f, 1.0f)); _matTable[2].diffuse(SLVec4f(1.0f, 0.5f, 0.0f, 1.0f)); SLCylinder* cylinder = new SLCylinder(0.15f, 0.8f, 1, 32, true, true, "tableLeg", &_matTable[0]); SLNode* tableLeg = new SLNode("Table Leg"); tableLeg->addMesh(cylinder); tableLeg->rotate(-90, 1, 0, 0); _rootNode->addChild(tableLeg); _table = new SLNode("turnTable"); _table->translate(0, 0.8f, 0); cylinder = new SLCylinder(0.5f, 0.04f, 1, 32, true, true, "tablePlate", &_matTable[1]); SLNode* tablePlate = new SLNode("Table Plate"); tablePlate->addMesh(cylinder); tablePlate->rotate(-90, 1, 0, 0); _table->addChild(tablePlate); SLNode* tableObjects = new SLNode("tableObjects"); _table->addChild(tableObjects); tableObjects->translate(0, 0.04f, 0); // test object SLNode* pot = SLAssImp::load("../_data/models/teapot.obj"); pot->translate(0, 0.138f, 0); pot->scale(0.2f); tableObjects->addChild(pot); _rootNode->addChild(_table); }
/*! SLAssimpImporter::loadMesh creates a new SLMesh an copies the meshs vertex data and triangle face indices. Normals & tangents are not loaded. They are calculated in SLMesh. */ SLMesh* SLAssimpImporter::loadMesh(aiMesh *mesh) { // Count first the NO. of triangles in the mesh SLuint numTriangles = 0; for(unsigned int i = 0; i < mesh->mNumFaces; ++i) if(mesh->mFaces[i].mNumIndices == 3) numTriangles++; // We only load meshes that contain triangles if (numTriangles==0 || mesh->mNumVertices==0) return nullptr; // create a new mesh. // The mesh pointer is added automatically to the SLScene::meshes vector. SLstring name = mesh->mName.data; SLMesh *m = new SLMesh(name.empty() ? "Imported Mesh" : name); // create position & normal vector m->P.clear(); m->P.resize(mesh->mNumVertices); // create normal vector if (mesh->HasNormals()) { m->N.clear(); m->N.resize(m->P.size()); } // allocate texCoord vector if needed if (mesh->HasTextureCoords(0)) { m->Tc.clear(); m->Tc.resize(m->P.size()); } // copy vertex positions & texCoord for(SLuint i = 0; i < m->P.size(); ++i) { m->P[i].set(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); if (m->N.size()) m->N[i].set(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z); if (m->Tc.size()) m->Tc[i].set(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y); } // create face index vector if (m->P.size() < 65536) { m->I16.clear(); m->I16.resize(mesh->mNumFaces * 3); // load face triangle indices only SLuint j = 0; for(SLuint i = 0; i < mesh->mNumFaces; ++i) { if(mesh->mFaces[i].mNumIndices == 3) { m->I16[j++] = mesh->mFaces[i].mIndices[0]; m->I16[j++] = mesh->mFaces[i].mIndices[1]; m->I16[j++] = mesh->mFaces[i].mIndices[2]; } } } else { m->I32.clear(); m->I32.resize(mesh->mNumFaces * 3); // load face triangle indices only SLuint j = 0; for(SLuint i = 0; i < mesh->mNumFaces; ++i) { if(mesh->mFaces[i].mNumIndices == 3) { m->I32[j++] = mesh->mFaces[i].mIndices[0]; m->I32[j++] = mesh->mFaces[i].mIndices[1]; m->I32[j++] = mesh->mFaces[i].mIndices[2]; } } } if (!m->N.size()) m->calcNormals(); // load joints if (mesh->HasBones()) { _skinnedMeshes.push_back(m); m->skeleton(_skeleton); m->Ji.resize(m->P.size()); m->Jw.resize(m->P.size()); // make sure to initialize the weights with 0 vectors std::fill(m->Ji.begin(), m->Ji.end(), SLVec4f(0, 0, 0, 0)); std::fill(m->Jw.begin(), m->Jw.end(), SLVec4f(0, 0, 0, 0)); for (SLuint i = 0; i < mesh->mNumBones; i++) { aiBone* joint = mesh->mBones[i]; SLJoint* slJoint = _skeleton->getJoint(joint->mName.C_Str()); // @todo On OSX it happens from time to time that slJoint is nullptr if (slJoint) { SLuint jointId = slJoint->id(); for (SLuint j = 0; j < joint->mNumWeights; j++) { // add the weight SLuint vertId = joint->mWeights[j].mVertexId; SLfloat weight = joint->mWeights[j].mWeight; m->addWeight(vertId, jointId, weight); // check if the bones max radius changed // @todo this is very specific to this loaded mesh, // when we add a skeleton instances class this radius // calculation has to be done on the instance! slJoint->calcMaxRadius(SLVec3f(mesh->mVertices[vertId].x, mesh->mVertices[vertId].y, mesh->mVertices[vertId].z)); } } else { SL_LOG("Failed to load joint of skeleton in SLAssimpImporter::loadMesh: %s\n", joint->mName.C_Str()); return nullptr; } } } return m; }