// MEG patches positions are reported line by line in the positions Matrix (same for positions) // mat is supposed to be filled with zeros // mat is the linear application which maps x (the unknown vector in symmetric system) -> binf (contrib to MEG response) void assemble_SurfSource2MEG(Matrix& mat, const Mesh& sources_mesh, const Sensors& sensors) { Matrix positions = sensors.getPositions(); Matrix orientations = sensors.getOrientations(); const unsigned nsquids = positions.nlin(); mat = Matrix(nsquids, sources_mesh.nb_vertices()); mat.set(0.0); for ( unsigned i = 0; i < nsquids; ++i) { PROGRESSBAR(i, nsquids); Vect3 p(positions(i, 0), positions(i, 1), positions(i, 2)); Matrix FergusonMat(3, mat.ncol()); FergusonMat.set(0.0); operatorFerguson(p, sources_mesh, FergusonMat, 0, 1.); for ( unsigned j = 0; j < mat.ncol(); ++j) { Vect3 fergusonField(FergusonMat(0, j), FergusonMat(1, j), FergusonMat(2, j)); Vect3 normalizedDirection(orientations(i, 0), orientations(i, 1), orientations(i, 2)); normalizedDirection.normalize(); mat(i, j) = fergusonField * normalizedDirection; } } mat = sensors.getWeightsMatrix() * mat; // Apply weights }
// Creates the DipSource2MEG Matrix with unconstrained orientations for the sources. // MEG patches positions are reported line by line in the positions Matrix (same for positions) // mat is supposed to be filled with zeros // sources is the name of a file containing the description of the sources - one dipole per line: x1 x2 x3 n1 n2 n3, x being the position and n the orientation. void assemble_DipSource2MEG(Matrix& mat, const Matrix& dipoles, const Sensors& sensors) { Matrix positions = sensors.getPositions(); Matrix orientations = sensors.getOrientations(); if ( dipoles.ncol() != 6) { std::cerr << "Dipoles File Format Error" << std::endl; exit(1); } // this Matrix will contain the field generated at the location of the i-th squid by the j-th source mat = Matrix(positions.nlin(), dipoles.nlin()); // the following routine is the equivalent of operatorFerguson for pointlike dipoles. for ( unsigned i = 0; i < mat.nlin(); ++i) { for ( unsigned j = 0; j < mat.ncol(); ++j) { Vect3 r(dipoles(j, 0), dipoles(j, 1), dipoles(j, 2)); Vect3 q(dipoles(j, 3), dipoles(j, 4), dipoles(j,5)); Vect3 diff(positions(i, 0), positions(i, 1), positions(i, 2)); diff -= r; double norm_diff = diff.norm(); Vect3 fergusonField = q ^ diff / (norm_diff * norm_diff * norm_diff); Vect3 normalizedDirection(orientations(i, 0), orientations(i, 1), orientations(i, 2)); normalizedDirection.normalize(); mat(i, j) = fergusonField * normalizedDirection * MU0 / (4.0 * M_PI); } } mat = sensors.getWeightsMatrix() * mat; // Apply weights }
// MEG patches positions are reported line by line in the positions Matrix (same for positions) // mat is supposed to be filled with zeros // mat is the linear application which maps x (the unknown vector in symmetric system) -> bFerguson (contrib to MEG response) void assemble_Head2MEG(Matrix& mat, const Geometry& geo, const Sensors& sensors) { Matrix positions = sensors.getPositions(); Matrix orientations = sensors.getOrientations(); const unsigned nbIntegrationPoints = sensors.getNumberOfPositions(); unsigned p0_p1_size = (geo.size() - geo.outermost_interface().nb_triangles()); Matrix FergusonMat(3*nbIntegrationPoints, geo.nb_vertices()); assemble_ferguson(geo, FergusonMat, positions); mat = Matrix(nbIntegrationPoints, p0_p1_size); mat.set(0.0); for ( unsigned i = 0; i < nbIntegrationPoints; ++i) { PROGRESSBAR(i, nbIntegrationPoints); for ( Vertices::const_iterator vit = geo.vertex_begin(); vit != geo.vertex_end(); ++vit) { Vect3 fergusonField(FergusonMat(3*i, vit->index()), FergusonMat(3*i+1, vit->index()), FergusonMat(3*i+2, vit->index())); Vect3 normalizedDirection(orientations(i, 0), orientations(i, 1), orientations(i, 2)); normalizedDirection.normalize(); mat(i, vit->index()) = fergusonField * normalizedDirection; } } mat = sensors.getWeightsMatrix() * mat; // Apply weights }
void Gdc2005Demo::updateUserControl() { const hkVector4 UP(0,1,0); // PC: Arrow keys (stick1) does 'old' style relative control (mapped to dpad, so can't use dpad aswell) // IJKL (stick0) does new style control // All others: Stick1 (left stick) does new style control // Stick0 (right stick) controls camera (in/out, left/right) // Dpad controls camera orbit (up, down, and left right too to be easier to control) //do we have a gamepad? bool haveProperGamePad = m_env->m_window->hasGamePads() && !(m_env->m_options->m_forceKeyboardGamepad); float stick0X; float stick0Y; float stick1X; float stick1Y; float dpadStickX = 0.0f; float dpadStickY = 0.0f; if (!haveProperGamePad) // PC etc { stick0X = m_env->m_gamePad->getStickPosX(1); stick0Y = m_env->m_gamePad->getStickPosY(1); stick1X = m_env->m_gamePad->getStickPosX(0); stick1Y = m_env->m_gamePad->getStickPosY(0); } else { stick0X = m_env->m_gamePad->getStickPosX(0); stick0Y = m_env->m_gamePad->getStickPosY(0); stick1X = m_env->m_gamePad->getStickPosX(1); stick1Y = m_env->m_gamePad->getStickPosY(1); dpadStickX = m_env->m_gamePad->getButtonState() & HKG_PAD_DPAD_RIGHT ? 1.0f : m_env->m_gamePad->getButtonState() & HKG_PAD_DPAD_LEFT ? -1.0f : 0; dpadStickY = m_env->m_gamePad->getButtonState() & HKG_PAD_DPAD_UP ? 1.0f : m_env->m_gamePad->getButtonState() & HKG_PAD_DPAD_DOWN ? -1.0f : 0; } const bool inputStick0X = hkMath::fabs( stick0X ) > 0.01f; const bool inputStick0Y = hkMath::fabs( stick0Y ) > 0.01f; // ignore char move on stick1 if in mouse mode const bool mouseMode = (m_env->m_gamePad->getButtonState() & HKG_PAD_BUTTON_L1) != 0; const bool inputStick1X = hkMath::fabs( stick1X ) > 0.01f && !mouseMode; const bool inputStick1Y = hkMath::fabs( stick1Y ) > 0.01f && !mouseMode; bool zeroInput = !(inputStick1Y | inputStick0Y | inputStick1X | inputStick0X); hkgCamera* currentCamera = m_env->m_window->getViewport(0)->getCamera(); if (!haveProperGamePad) { if (inputStick0Y || inputStick0X) { m_forwardSpeed = stick0Y; const hkReal stickDiff = (m_forwardSpeed - m_dampedForwardSpeed); const hkReal stickGain = m_options.m_Misc.m_walkToRunSpeed; m_dampedForwardSpeed += stickDiff * stickGain; m_dampedTurnAngle = -0.04f * stick0X; } } else // stick0 and dpad does the camera { if (inputStick0Y || inputStick0X || (hkMath::fabs(dpadStickX) > 0.01f) || (hkMath::fabs(dpadStickY) > 0.01f)) { // Need to control camera // Simple rotate about the point of interest (orbit left/right, zoom in/out) _deadzone(stick0X, stick0X); if (inputStick0X) { currentCamera->rotateAboutTo(0.1f*stick0X, (const float*)&UP, true ); } if (inputStick0Y) { currentCamera->dolly(-0.1f*stick0Y, false, true ); } // Dpad orbit up down (and left right to be used) if (hkMath::fabs(dpadStickY) > 0.01f) { float r[3]; currentCamera->getRight(r); currentCamera->rotateAboutTo(-0.03f*dpadStickY, r, true); } if (hkMath::fabs(dpadStickX) > 0.01f) { currentCamera->rotateAboutTo(0.03f*dpadStickX, (const float*)&UP, true ); } } } // normal stick style (maps to IJKL keys on PC) if (inputStick1Y || inputStick1X) { hkVector4 dv, tv, rv; currentCamera->getDir((float*)&dv); tv.setCross( UP, dv); dv.setCross(tv, UP ); currentCamera->getRight((float*)&rv); tv.setCross( UP, rv); rv.setCross(tv, UP ); dv.fastNormalize3(); rv.fastNormalize3(); // accont for deadzone (as hkg will deadzone, but does not normalize the non deadzone back to 0..1) _deadzone(stick1X, stick1Y); dv.mul4( stick1Y ); rv.mul4( stick1X ); m_desiredDirection.setAdd4(dv, rv); float dirSquared = stick1X*stick1X + stick1Y*stick1Y; if ( dirSquared > 0.05f) // going somewhere.. { m_forwardSpeed = hkMath::sqrt( dirSquared ); // see how far off we are from facing along desired: hkRotation rm; rm.set( m_currentTransform.getRotation() ); hkVector4 facingDir = rm.getColumn(2); hkVector4 normalizedDirection( m_desiredDirection ); normalizedDirection.fastNormalize3(); hkVector4 tc; tc.setCross(facingDir, normalizedDirection ); hkReal cosTheta = facingDir.dot3( normalizedDirection ); hkReal angle = hkMath::acos( cosTheta ); if (tc.dot3(UP) < 0) { angle *= -1; } m_dampedTurnAngle = 0.1f * angle; const hkReal stickDiff = (m_forwardSpeed - m_dampedForwardSpeed); const hkReal stickGain = m_options.m_Misc.m_walkToRunSpeed * cosTheta; m_dampedForwardSpeed += stickDiff * stickGain; } else // zero effect on stick1 { zeroInput |= !(inputStick0Y || inputStick0X); } } if (zeroInput) { m_forwardSpeed = 0; m_dampedForwardSpeed -= m_dampedForwardSpeed*0.5f; m_dampedTurnAngle = 0; } }