///TODO: render the system (ie draw the particles) void ClothSystem::draw() { float temp = sqrt(m_numParticles); int numParticles = int(temp); for (int i = 0; i < numParticles; i++) { for(int j = 0; j < numParticles; j++){ int index = indexOf(i, j); vector<Vector2f> neighbors = getNeighbors(i,j); Vector3f pos = m_vVecState[index]; glPushMatrix(); glBegin(GL_LINES); for(int n = 0; n < neighbors.size(); n++){ Vector2f pair = neighbors[n]; Vector3f other_pos = m_vVecState[indexOf(pair[0], pair[1])]; Vector2f test = pair - Vector2f(i, j); if(test.abs() == 1.0){ glVertex3f(pos[0], pos[1], pos[2]); glVertex3f(other_pos[0], other_pos[1], other_pos[2]); } } glEnd(); glTranslatef(pos[0], pos[1], pos[2]); glutSolidSphere(0.075f,10.0f,10.0f); glPopMatrix(); } } }
Vector3f ClothSystem::sumForces(int i, int j, vector<Vector3f> state){ //anchored case int numParticles = int(sqrt(m_numParticles)); if( (i == 0 || i == numParticles - 1) && j == 0){ return Vector3f(0,0,0); } float mass = 5; int k = 4; float r = 0.5; //computing the gravity vector Vector3f Fg = mass * Vector3f(0,-1,0); //computing the drag vector Vector3f Fd = -1.0 * k * state[ClothSystem::indexOf(i,j) + 1]; Vector3f pos = state[ClothSystem::indexOf(i,j)]; Vector3f F_spring = Vector3f(0,0,0); vector<Vector2f> neighbors = getNeighbors(i, j); for(int n = 0; n < neighbors.size(); n++){ Vector2f pair = neighbors[n]; Vector3f other_pos = state[indexOf(pair[0], pair[1])]; Vector2f test = pair - Vector2f(i, j); //Adjacent neighbors only if(test.abs() == 1.0){ // if(pair[0] - i > 0){ Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); } } neighbors = getShear(i, j); for(int n = 0; n < neighbors.size(); n++){ Vector2f pair = neighbors[n]; Vector3f other_pos = state[indexOf(pair[0], pair[1])]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); } neighbors = getFlex(i, j); if(neighbors.size() == 3){ //top left if(inFlex(i, j + 2) && inFlex(i+2, j)){ Vector3f other_pos = state[indexOf(i, j+2)]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); other_pos = state[indexOf(i+2, j)]; d = pos - other_pos; length = d.abs(); scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); }//top right else if(inFlex(i-2,j) && inFlex(i,j+2)){ Vector3f other_pos = state[indexOf(i-2, j)]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); other_pos = state[indexOf(i, j+2)]; d = pos - other_pos; length = d.abs(); scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); }//bottom left else if(inFlex(i, j-2) && inFlex(i+2,j)){ Vector3f other_pos = state[indexOf(i, j-2)]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); other_pos = state[indexOf(i+2, j)]; d = pos - other_pos; length = d.abs(); scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); }//bottom right else if(inFlex(i,j-2) && inFlex(i-2, j)){ Vector3f other_pos = state[indexOf(i, j-2)]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); other_pos = state[indexOf(i-2, j)]; d = pos - other_pos; length = d.abs(); scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + (scalar * d); } }else if(neighbors.size() == 1){ Vector3f other_pos = state[indexOf(neighbors[0][0], neighbors[0][1])]; Vector3f d = pos - other_pos; float length = d.abs(); float scalar = -1.0 * k * (length - r) / length; F_spring = F_spring + ( scalar * d); } return (1.0/mass) * (Fg + Fd + F_spring); }
void QD3D11MultiViewportViewer::mouseMoveEvent( QMouseEvent* event ) { Vector2i curPos( event->x(), event->y() ); Vector2f delta = curPos - m_prevPos; #if 1 float pitchSpeed = m_flipMouseUpDown ? m_mousePitchSpeed : -m_mousePitchSpeed; const float yawSpeed = 0.005f; const float panSpeed = 0.005f; const float walkSpeed = -0.005f; Matrix3f worldToCamera = m_perspectiveCamera.viewMatrix().getSubmatrix3x3( 0, 0 ); Matrix3f cameraToWorld = m_perspectiveCamera.inverseViewMatrix().getSubmatrix3x3( 0, 0 ); Vector3f eye = m_perspectiveCamera.eye(); Vector3f x = m_perspectiveCamera.right(); Vector3f y = m_perspectiveCamera.up(); Vector3f z = m_perspectiveCamera.forward(); // rotate if( event->buttons() == Qt::LeftButton ) { // pitch around the local x axis float pitch = pitchSpeed * delta.y; Matrix3f pitchMatrix = Matrix3f::rotateX( pitch ); y = cameraToWorld * pitchMatrix * worldToCamera * y; z = cameraToWorld * pitchMatrix * worldToCamera * z; // yaw around the world up vector float yaw = yawSpeed * delta.x; Matrix3f yawMatrix = m_groundPlaneToWorld * Matrix3f::rotateY( yaw ) * m_worldToGroundPlane; x = yawMatrix * x; y = yawMatrix * y; z = yawMatrix * z; m_perspectiveCamera.setLookAt( eye, eye + z, y ); } // walk else if( event->buttons() == Qt::RightButton ) { float dx = panSpeed * delta.x; float dz = walkSpeed * delta.y; translate( dx, 0, dz ); } // move up/down else if( event->buttons() == Qt::MiddleButton ) { float dy = -panSpeed * delta.y; translate( 0, dy, 0 ); } #else if(event->buttons() & Qt::RightButton) //rotate { float rotSpeed = 0.005f; //radians per pixel Quat4f rotation; rotation.setAxisAngle(rotSpeed * delta.abs(), Vector3f(-delta[1], -delta[0], 0)); Matrix3f rotMatrix = Matrix3f::rotation(rotation); Matrix3f viewMatrix = m_camera.getViewMatrix().getSubmatrix3x3(0, 0); rotMatrix = viewMatrix.transposed() * rotMatrix * viewMatrix; Vector3f eye, center, up; m_camera.getLookAt(&eye, ¢er, &up); m_camera.setLookAt(center + rotMatrix * (eye - center), center, rotMatrix * up); } else if(event->buttons() & Qt::LeftButton) //translate { float speed = 10.f; Vector3f screenDelta(delta[0], delta[1], 0); screenDelta[0] /= -double(width()); screenDelta[1] /= double(height()); Matrix4f iViewProjMatrix = m_camera.getInverseViewProjectionMatrix(); Vector3f worldDelta = iViewProjMatrix.getSubmatrix3x3(0, 0) * (speed * screenDelta); Vector3f eye, center, up; m_camera.getLookAt(&eye, ¢er, &up); m_camera.setLookAt(eye + worldDelta, center + worldDelta, up); } #endif m_prevPos = curPos; update(); }