void WindowAnotationManager::on_actionWeights4_triggered() { VectorF weights; weights.push_back(1.0); weights.push_back(0.5); weights.push_back(0.25); weights.push_back(0.125); tracker->weights = weights; updateTrackerInfo(); }
void LineArtist::drawLine(f32 x1, f32 y1, f32 x2, f32 y2, const Color& color) { sf::Vertex vtxList[4]; VectorF begin = { x1, y1 }; VectorF end = { x2, y2 }; VectorF direction = end - begin; direction.normalize(); VectorF perpendicularVec = { -direction.y, direction.x }; VectorF offset = (m_thickness / 2.0f) * perpendicularVec; VectorF tempVtxList[4] = { { begin + offset }, { end + offset }, { end - offset }, { begin - offset } }; const sf::Color sfColor = sf::Color(color.getRgba()); for (i32 i = 0; i < 4; ++i) { vtxList[i].position = { tempVtxList[i].x, tempVtxList[i].y }; vtxList[i].color = sfColor; } m_sharedWin.getObject()->draw(vtxList, 4, sf::Quads, m_renderStates); }
void VertexIsotropicOffsetParameter::apply(VectorF& results, const PatternParameter::Variables& vars) { const size_t dim = m_wire_network->get_dim(); const size_t num_vertices = m_wire_network->get_num_vertices(); const size_t roi_size = m_roi.size(); const VectorF center = m_wire_network->center(); const VectorF bbox_max = m_wire_network->get_bbox_max(); assert(results.size() == dim * num_vertices); assert(roi_size == m_transforms.size()); if (m_formula != "") evaluate_formula(vars); const MatrixFr& vertices = m_wire_network->get_vertices(); size_t seed_vertex_index = m_roi.minCoeff(); VectorF seed_vertex = vertices.row(seed_vertex_index); VectorF seed_offset = VectorF::Zero(dim); seed_offset = (bbox_max - center).cwiseProduct(m_dof_dir) * m_value; for (size_t i=0; i<roi_size; i++) { size_t v_idx = m_roi[i]; assert(v_idx < num_vertices); const MatrixF& trans = m_transforms[i]; results.segment(v_idx*dim, dim) += trans * seed_offset; } }
void VertexNormalAttribute::compute_vertex_normals_from_face(Mesh& mesh) { const size_t dim = mesh.get_dim(); const size_t num_vertices = mesh.get_num_vertices(); const size_t num_faces = mesh.get_num_faces(); const size_t vertex_per_face = mesh.get_vertex_per_face(); const VectorF& normals = get_attribute(mesh, "face_normal"); const VectorF& areas = get_attribute(mesh, "face_area"); assert(normals.size() == 3 * num_faces); assert(areas.size() == num_faces); VectorF& v_normals = m_values; v_normals = VectorF::Zero(dim * num_vertices); for (size_t i=0; i<num_faces; i++) { VectorI face = mesh.get_face(i); assert(face.size() == vertex_per_face); VectorF face_normal = normals.segment(i*dim, dim); Float face_area = areas[i]; for (size_t j=0; j<vertex_per_face; j++) { size_t vi = face[j]; v_normals.segment(vi*dim, dim) += face_normal * face_area; } } for (size_t i=0; i<num_vertices; i++) { VectorF n = v_normals.segment(dim*i, dim); Float n_len = n.norm(); if (n_len > 0.0) n /= n_len; v_normals.segment(dim*i, dim) = n; } }
void GFXDrawUtil::drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color ) { GFXTransformSaver saver; // Direction and length of the arrow. VectorF dir = end - start; F32 len = dir.len(); dir.normalize(); len *= 0.2f; // Base of the cone will be a distance back from the end of the arrow // proportional to the total distance of the arrow... 0.3f looks about right. Point3F coneBase = end - dir * len * 0.3f; // Calculate the radius of the cone given that we want the cone to have // an angle of 25 degrees (just because it looks good). F32 coneLen = ( end - coneBase ).len(); F32 coneDiameter = mTan( mDegToRad(25.0f) ) * coneLen; // Draw the cone on at the arrow's tip. drawCone( desc, coneBase, end, coneDiameter / 2.0f, color ); // Get the difference in length from // the start of the cone to the end // of the cylinder so we can put the // end of the cylinder right against where // the cone starts. Point3F coneDiff = end - coneBase; // Draw the cylinder. F32 stickRadius = len * 0.025f; drawCylinder( desc, start, end - coneDiff, stickRadius, color ); }
void OBJWriter::write_mesh(Mesh& mesh) { using namespace OBJWriterHelper; std::ofstream fout(m_filename.c_str()); if (!is_anonymous()) { fout << "# Generated with PyMesh" << std::endl; } VectorF texture; VectorI texture_indices; if (mesh.has_attribute("corner_texture")) { texture = mesh.get_attribute("corner_texture"); const size_t num_faces = mesh.get_num_faces(); const size_t vertex_per_face = mesh.get_vertex_per_face(); if (texture.size() != num_faces * vertex_per_face * 2) { // Texture invalid. texture.resize(0); } else { write_texture(fout, texture); texture_indices.resize(num_faces * vertex_per_face); for (size_t i=0; i<num_faces; i++) { for (size_t j=0; j<vertex_per_face; j++) { texture_indices[i*vertex_per_face+j] = i*vertex_per_face+j; } } } } write_vertices(fout, mesh.get_vertices(), mesh.get_dim()); write_faces(fout, mesh.get_faces(), mesh.get_vertex_per_face(), texture_indices); fout.close(); }
void IsotropicDofExtractor::check_bbox_is_isotropic() const { VectorF half_size = 0.5 * (m_bbox_max - m_bbox_min); VectorF gap = (half_size.array() - m_bbox_half_size).cwiseAbs(); if (gap.minCoeff() > 1e-12) { throw RuntimeError("BBox is not isotropic."); } }
void write_texture(std::ofstream& fout, const VectorF& uv) { assert(uv.size() % 2 == 0); const size_t num_uvs = uv.size() / 2; for (size_t i=0; i<num_uvs; i++) { fout << "vt " << uv[i*2] << " " << uv[i*2+1] << std::endl; } }
VectorF convert_voxel_attribute_to_vertex_attribute( Mesh& mesh, const VectorF& attribute) { const size_t num_vertices = mesh.get_num_vertices(); const size_t vertex_per_voxel = mesh.get_vertex_per_voxel(); const size_t num_voxels = mesh.get_num_voxels(); const size_t attr_size = attribute.size(); const size_t stride = attr_size / num_voxels; const VectorI& voxels = mesh.get_voxels(); if (!mesh.has_attribute("voxel_volume")) { mesh.add_attribute("voxel_volume"); } const VectorF& weights = mesh.get_attribute("voxel_volume"); VectorF result = VectorF::Zero(num_vertices * stride); VectorF result_weights = VectorF::Zero(num_vertices); for (size_t i=0; i<num_voxels; i++) { const VectorI& voxel = voxels.segment(i*vertex_per_voxel, vertex_per_voxel); Float per_vertex_weight = weights[i] / vertex_per_voxel; for (size_t j=0; j<vertex_per_voxel; j++) { result_weights[voxel[j]] += per_vertex_weight; result.segment(voxel[j]*stride, stride) += per_vertex_weight * attribute.segment(i*stride, stride); } } for (size_t i=0; i<num_vertices; i++) { result.segment(i*stride, stride) /= result_weights[i]; } return result; }
VectorF convert_face_attribute_to_vertex_attribute( Mesh& mesh, const VectorF& attribute) { const size_t num_vertices = mesh.get_num_vertices(); const size_t vertex_per_face = mesh.get_vertex_per_face(); const size_t num_faces = mesh.get_num_faces(); const size_t attr_size = attribute.size(); const size_t stride = attr_size / num_faces; const VectorI& faces = mesh.get_faces(); const VectorF& weights = mesh.get_attribute("face_area"); VectorF result = VectorF::Zero(num_vertices * stride); VectorF result_weights = VectorF::Zero(num_vertices); for (size_t i=0; i<num_faces; i++) { const VectorI& face = faces.segment(i*vertex_per_face, vertex_per_face); Float per_vertex_weight = weights[i] / vertex_per_face; for (size_t j=0; j<vertex_per_face; j++) { result_weights[face[j]] += per_vertex_weight; result.segment(face[j]*stride, stride) += per_vertex_weight * attribute.segment(i*stride, stride); } } for (size_t i=0; i<num_vertices; i++) { result.segment(i*stride, stride) /= result_weights[i]; } return result; }
MatrixFr OffsetParameters::evaluate(const OffsetParameters::Variables& vars) { const size_t dim = m_wire_network->get_dim(); const size_t size = m_wire_network->get_num_vertices(); VectorF offset = VectorF::Ones(size * dim) * m_default_offset; for (auto param : m_params) { param->apply(offset, vars); } MatrixFr results = Eigen::Map<MatrixFr>(offset.data(), size, dim); return results; }
S32 TSShapeInstance::setDetailFromPosAndScale( const SceneRenderState *state, const Point3F &pos, const Point3F &scale ) { VectorF camVector = pos - state->getDiffuseCameraPosition(); F32 dist = getMax( camVector.len(), 0.01f ); F32 invScale = ( 1.0f / getMax( getMax( scale.x, scale.y ), scale.z ) ); return setDetailFromDistance( state, dist * invScale ); }
Float LinearTetrahedronIntegrator::integrate_grad_C(size_t elem_idx, size_t local_func_i, size_t local_func_j, const MatrixF& C) { const Vector4F coord(1.0/4.0, 1.0/4.0, 1.0/4.0, 1.0/4.0); const VectorF grad_i = m_shape_func->evaluate_grad( elem_idx, local_func_i, coord); const VectorF grad_j = m_shape_func->evaluate_grad( elem_idx, local_func_j, coord); const Float vol = m_mesh->getElementVolume(elem_idx); return grad_i.dot(C * grad_j) * vol; }
void InflatorEngine::with_abs_geometry_correction(const VectorF& correction) { if (correction.size() != m_wire_network->get_dim()) { std::stringstream err_msg; err_msg << "Absolute geometry offset dimension mismatch. Expect " << m_wire_network->get_dim() << " but get " << correction.size() << " instead."; throw RuntimeError(err_msg.str()); } m_abs_correction = correction; }
VectorF PointLocator::compute_barycentric_coord(const VectorF& v, size_t elem_idx) { const size_t dim = m_mesh->get_dim(); MatrixF solver = m_barycentric_solvers.block(elem_idx*dim, 0, dim, dim); VectorF last_v = m_last_vertices.row(elem_idx); VectorF sol = solver * (v - last_v); VectorF barycentric_coord(m_vertex_per_element); barycentric_coord.segment(0, dim) = sol; barycentric_coord[dim] = 1.0 - sol.sum(); return barycentric_coord; }
void ClippedPolyList::generateNormals() { PROFILE_SCOPE( ClippedPolyList_GenerateNormals ); AssertFatal(mNormalList.size() == mVertexList.size(), "Normals count does not match vertex count!"); U32 i, polyCount; VectorF normal; PolyListIterator polyIter; IndexListIterator indexIter; Vector<VectorF>::iterator normalIter = mNormalList.begin(); U32 n = 0; for ( ; normalIter != mNormalList.end(); normalIter++, n++ ) { // Skip normals that already have values. if ( !normalIter->isZero() ) continue; // Average all the face normals which // share this vertex index. indexIter = mIndexList.begin(); normal.zero(); polyCount = 0; i = 0; for ( ; indexIter != mIndexList.end(); indexIter++, i++ ) { if ( n != *indexIter ) continue; polyIter = mPolyList.begin(); for ( ; polyIter != mPolyList.end(); polyIter++ ) { const Poly& poly = *polyIter; if ( i < poly.vertexStart || i > poly.vertexStart + poly.vertexCount ) continue; ++polyCount; normal += poly.plane; } } // Average it. if ( polyCount > 0 ) normal /= (F32)polyCount; // Note: we use a temporary for the normal averaging // then copy the result to limit the number of arrays // we're touching during the innermost loop. *normalIter = normal; } }
void correct_tet_orientation(const VectorF& vertices, VectorI& voxels) { const size_t num_voxels = voxels.size() / 4; for (size_t i=0; i<num_voxels; i++) { const VectorI tet = voxels.segment(i*4, 4); const Vector3F& v1 = vertices.segment(tet[0]*3, 3); const Vector3F& v2 = vertices.segment(tet[1]*3, 3); const Vector3F& v3 = vertices.segment(tet[2]*3, 3); const Vector3F& v4 = vertices.segment(tet[3]*3, 3); if (!positive_orientated(v1, v2, v3, v4)) { voxels[i*4] = tet[1]; voxels[i*4+1] = tet[0]; } } }
void WireNetwork::translate(const VectorF& offset) { if (offset.size() != m_dim) { std::stringstream err_msg; err_msg << "Offset is of dim (" << offset.size() << "), expecting (" << m_dim << ")"; throw RuntimeError(err_msg.str()); } const size_t num_vertices = get_num_vertices(); for (size_t i=0; i<num_vertices; i++) { m_vertices.row(i) += offset; } update_bbox(); }
void HoverVehicle::updateDustTrail( F32 dt ) { // Check to see if we're moving. VectorF velocityVector = getVelocity(); F32 velocity = velocityVector.len(); if( velocity > 2.0 ) { velocityVector.normalize(); emitDust( mDustTrailEmitter, mDataBlock->triggerTrailHeight, mDataBlock->dustTrailOffset, ( U32 )( dt * 1000 * ( velocity / mDataBlock->dustTrailFreqMod ) ), velocityVector ); } }
bool Trigger::testObject(GameBase* enter) { if (mTriggerPolyhedron.pointList.size() == 0) return false; mClippedList.clear(); SphereF sphere; sphere.center = (mWorldBox.minExtents + mWorldBox.maxExtents) * 0.5; VectorF bv = mWorldBox.maxExtents - sphere.center; sphere.radius = bv.len(); enter->buildPolyList(PLC_Collision, &mClippedList, mWorldBox, sphere); return mClippedList.isEmpty() == false; }
void TerrainCellMaterial::setTransformAndEye( const MatrixF &modelXfm, const MatrixF &viewXfm, const MatrixF &projectXfm, F32 farPlane ) { PROFILE_SCOPE( TerrainCellMaterial_SetTransformAndEye ); MatrixF modelViewProj = projectXfm * viewXfm * modelXfm; MatrixF invViewXfm( viewXfm ); invViewXfm.inverse(); Point3F eyePos = invViewXfm.getPosition(); MatrixF invModelXfm( modelXfm ); invModelXfm.inverse(); Point3F objEyePos = eyePos; invModelXfm.mulP( objEyePos ); VectorF vEye = invViewXfm.getForwardVector(); vEye.normalize( 1.0f / farPlane ); for ( U32 i=0; i < mPasses.size(); i++ ) { Pass &pass = mPasses[i]; pass.consts->setSafe( pass.modelViewProjConst, modelViewProj ); if( pass.viewToObj->isValid() || pass.worldViewOnly->isValid() ) { MatrixF worldViewOnly = viewXfm * modelXfm; pass.consts->setSafe( pass.worldViewOnly, worldViewOnly ); if( pass.viewToObj->isValid() ) { worldViewOnly.affineInverse(); pass.consts->set( pass.viewToObj, worldViewOnly); } } pass.consts->setSafe( pass.eyePosWorldConst, eyePos ); pass.consts->setSafe( pass.eyePosConst, objEyePos ); pass.consts->setSafe( pass.objTransConst, modelXfm ); pass.consts->setSafe( pass.worldToObjConst, invModelXfm ); pass.consts->setSafe( pass.vEyeConst, vEye ); } }
void WireNetwork::scale(const VectorF& factors) { if (factors.size() != m_dim) { std::stringstream err_msg; err_msg << "Scaling factors is of dim (" << factors.size() << "), expecting (" << m_dim << ")"; throw RuntimeError(err_msg.str()); } const size_t num_vertices = get_num_vertices(); for (size_t i=0; i<num_vertices; i++) { const VectorF& v = m_vertices.row(i); m_vertices.row(i) = v.cwiseProduct(factors); } update_bbox(); }
void VertexOffsetParameter::apply(VectorF& results, const PatternParameter::Variables& vars) { const VectorF bbox_min = m_wire_network->get_bbox_min(); const VectorF bbox_max = m_wire_network->get_bbox_max(); const VectorF center = 0.5 * (bbox_min + bbox_max); const VectorF half_bbox_size = bbox_max - center; const size_t dim = m_wire_network->get_dim(); const size_t num_vertices = m_wire_network->get_num_vertices(); const size_t roi_size = m_roi.size(); assert(m_axis < dim); assert(results.size() == dim * num_vertices); if (m_formula != "") evaluate_formula(vars); const MatrixFr& vertices = m_wire_network->get_vertices(); for (size_t i=0; i<roi_size; i++) { size_t v_idx = m_roi[i]; assert(v_idx < num_vertices); const VectorF& v = vertices.row(v_idx); assert(fabs(v[m_axis] - center[m_axis]) > 1e-12); Float sign = v[m_axis] - center[m_axis] > 0.0 ? 1.0 : -1.0; results[v_idx * dim + m_axis] = sign * half_bbox_size[m_axis] * m_value; } }
void TilerEngine::normalize_unit_wire(const VectorF& cell_size) { if (cell_size.minCoeff() <= 1e-30) { const size_t dim = cell_size.size(); if (dim == 3) throw RuntimeError("It seems the 3D wires are flat."); else if (dim == 2) throw RuntimeError("It seems the 2D wires are degenerated/linear."); else throw NotImplementedError("Unsupported dimension!"); } VectorF factors = cell_size.cwiseQuotient( m_unit_wire_network->get_bbox_max() - m_unit_wire_network->get_bbox_min()); m_unit_wire_network->center_at_origin(); m_unit_wire_network->scale(factors); }
void write_vertices(std::ofstream& fout, const VectorF& vertices, const size_t dim) { if (dim != 2 && dim != 3) { throw IOError("Unsupported mesh dimension: " + std::to_string(dim)); } fout.precision(16); size_t num_vertices = vertices.size() / dim; for (size_t i=0; i<num_vertices; i++) { const auto& v = vertices.segment(i*dim, dim); fout << "v"; for (size_t j=0; j<dim; j++) { fout << " " << v[j]; } fout << std::endl; } }
void ScatterSky::_conformLights() { _initCurves(); F32 val = mCurves[0].getVal( mTimeOfDay ); mNightInterpolant = 1.0f - val; VectorF lightDirection; F32 brightness; // Build the light direction from the azimuth and elevation. F32 yaw = mDegToRad(mClampF(mSunAzimuth,0,359)); F32 pitch = mDegToRad(mClampF(mSunElevation,-360,+360)); MathUtils::getVectorFromAngles(lightDirection, yaw, pitch); lightDirection.normalize(); mSunDir = -lightDirection; yaw = mDegToRad(mClampF(mMoonAzimuth,0,359)); pitch = mDegToRad(mClampF(mMoonElevation,-360,+360)); MathUtils::getVectorFromAngles( mMoonLightDir, yaw, pitch ); mMoonLightDir.normalize(); mMoonLightDir = -mMoonLightDir; brightness = mCurves[2].getVal( mTimeOfDay ); if ( mNightInterpolant >= 1.0f ) lightDirection = -mMoonLightDir; mLight->setDirection( -lightDirection ); mLight->setBrightness( brightness * mBrightness ); mLightDir = lightDirection; // Have to do interpolation // after the light direction is set // otherwise the sun color will be invalid. _interpolateColors(); mLight->setAmbient( mAmbientColor ); mLight->setColor( mSunColor ); mLight->setCastShadows( mCastShadows ); FogData fog = getSceneManager()->getFogData(); fog.color = mFogColor; getSceneManager()->setFogData( fog ); }
void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 radius, const ColorI &color ) { VectorF uvec = tipPnt - basePnt; F32 height = uvec.len(); uvec.normalize(); MatrixF mat( true ); MathUtils::getMatrixFromUpVector( uvec, &mat ); mat.setPosition(basePnt); Point3F scale( radius, radius, height * 2 ); mat.scale(scale); GFXTransformSaver saver; mDevice->pushWorldMatrix(); mDevice->multWorld(mat); S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints * 4 + 4, GFXBufferTypeVolatile); verts.lock(); for (S32 i=0; i<numPoints + 1; i++) { S32 imod = i % numPoints; verts[i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f); verts[i].color = color; verts[i + numPoints + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0); verts[i + numPoints + 1].color = color; verts[2*numPoints + 2 + 2 * i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f); verts[2*numPoints + 2 + 2 * i].color = color; verts[2*numPoints + 2 + 2 * i + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0); verts[2*numPoints + 2 + 2 * i + 1].color = color; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders( GFXDevice::GSModColorTexture ); mDevice->drawPrimitive( GFXTriangleFan, 0, numPoints ); mDevice->drawPrimitive( GFXTriangleFan, numPoints + 1, numPoints ); mDevice->drawPrimitive( GFXTriangleStrip, 2 * numPoints + 2, 2 * numPoints); mDevice->popWorldMatrix(); }
void EigenSolver::compute_batch_symmetric_2x2(const VectorF& matrices) { const size_t dim = 2; const size_t flatten_size = 3; const size_t num_matrices = matrices.size() / flatten_size; m_eigen_values = VectorF(num_matrices * dim); m_eigen_vectors = MatrixF(num_matrices * dim, dim); for (size_t i=0; i<num_matrices; i++) { const VectorF& entries = matrices.segment(i*flatten_size, flatten_size); MatrixF M(dim, dim); size_t base_idx = i*flatten_size; M << matrices[base_idx ], matrices[base_idx+2], matrices[base_idx+2], matrices[base_idx+1], m_solver.compute(M); m_eigen_values.segment(i*dim, dim) = m_solver.eigenvalues().real(); m_eigen_vectors.block(i*dim, 0, dim, dim) = m_solver.eigenvectors().real(); } }
std::list<std::function<MatrixFr(const MatrixFr&)> > get_tiling_operators( const VectorF& ref_pt, const VectorF& cell_size, const std::vector<VectorI>& indices) { std::list<std::function<MatrixFr(const MatrixFr&)> > operators; for (auto index : indices) { VectorF cur_pt = cell_size.cwiseProduct(index.cast<Float>()); VectorF offset = cur_pt - ref_pt; operators.push_back( [=] (const MatrixFr& vertices) { MatrixFr result(vertices); result.rowwise() += offset.transpose(); return result; }); } return operators; }
int main(int argc, char *argv[]) { QApplication app(argc, argv); QCommandLineParser parser; parser.addOption(QCommandLineOption("directory", "Directory containing video files", "directory")); parser.addOption(QCommandLineOption("model", "Left Vebtricle model file", "model")); parser.addHelpOption(); parser.process(app); QString directory, model; if (!parser.isSet("directory")) directory = QFileDialog::getExistingDirectory(0, "Select directory containing videos"); else directory = parser.value("directory"); if (!parser.isSet("model")) model = QFileDialog::getOpenFileName(0, "Select model"); else model = parser.value("model"); if (directory.isEmpty() || directory.isNull() || model.isEmpty() || model.isNull()) return 0; PCA *pca = new PCA(); StatisticalShapeModel *shapeModel = new StatisticalShapeModel(pca); ShapeNormalizerBase *normalizer = new ShapeNormalizerIterativeStatisticalShape(shapeModel); LongitudinalStrain *strain = new LongitudinalStrain(normalizer, 0, 0); cv::FileStorage strainStorage(model.toStdString(), cv::FileStorage::READ); //cv::FileStorage strainStorage("potkani", cv::FileStorage::READ); strain->deserialize(strainStorage); ListOfImageProcessing processing; StrainResultProcessingBase *postProcessing = new StrainResProcFloatingAvg(3); PointTrackerBase *pointTracker = new PointTrackerOpticalFlow(21); VectorF weights; weights.push_back(1.0f); ShapeTracker *tracker = new ShapeTracker(strain, processing, pointTracker, postProcessing, weights); qDebug() << "Tracker initializated"; // create GUI WindowAnotationManager w(directory, tracker); w.show(); return app.exec(); }