void InputManager::BuildCamToWorld() { dvec3 gaze, up, v, u, w; gaze.x = sin(d2r(transforms.elevation)) * cos(d2r(transforms.heading)); gaze.y = 0 - cos(d2r(transforms.elevation)); gaze.z = sin(d2r(transforms.elevation)) * sin(d2r(transforms.heading)); if(transforms.elevation == 0) { //If Looking straight down, change the up vector to the heading up = dvec3(cos(d2r(transforms.heading)), 0, sin(d2r(transforms.heading))); } else if(transforms.elevation == 180) { //If looking straight up, change the up vector to the negative heading up = dvec3(0 - cos(d2r(transforms.heading)), 0, 0 - sin(d2r(transforms.heading))); } else { up = dvec3(0,1,0); } w.x = 0 - gaze.x; w.y = 0 - gaze.y; w.z = 0 - gaze.z; //Shouldn't be necessary, but just in case... w = normalize(w); u = cross(up, w); u = normalize(u); v = cross(w, u); v = normalize(v); dmat4x4 changeBase = dmat4x4( u.x, u.y, u.z, 0, v.x, v.y, v.z, 0, gaze.x, gaze.y, gaze.z, 0, 0 , 0 , 0 , 1); changeBase = transpose(changeBase); dmat4x4 eye2origin = dmat4x4( 1, 0, 0, 0 - transforms.xPos, 0, 1, 0, 0 - transforms.yPos, 0, 0, 1, 0 - transforms.zPos, 0, 0, 0, 1); eye2origin = transpose(eye2origin); dmat4x4 changeBaseINV = inverse(changeBase); dmat4x4 eye2originINV = inverse(eye2origin); rotateToWorld = changeBaseINV; camToWorld = eye2originINV * changeBaseINV; }
Camera::Camera() : m_fov( 45.0 ), m_aspect_ratio( 1.0 ) { double temp_pos[] = { 0.0, 0.0, 0.0 }; m_position = dvec3( temp_pos ); double temp_dir[] = { 0.0, 0.0, -1.0 }; m_direction = dvec3( temp_dir ); double temp_up[] = { 0.0, 1.0, 0.0 }; m_up = dvec3( temp_up ); double temp_right[] = { 1.0, 0.0, 0.0 }; m_right = dvec3( temp_right ); }
//-------------------------------------------------------------------------------------- // Figure out the velocity based on keyboard input & drag if any //-------------------------------------------------------------------------------------- void CBaseCamera::UpdateVelocity( double fElapsedTime ) { dmat4 mRotDelta; dvec3 vAccelMouse(0); if (mMouseRotates) { mRotVelocity = mMouseDelta * mRotationScaler; } else { vAccelMouse += dvec3(-mMouseDelta.x, mMouseDelta.y, 0.0f); } dvec3 vAccelKeyboard = mKeyboardDirection; // Normalize vector so if moving 2 dirs (left & forward), // the camera doesn't move faster than if moving in 1 dir if (!isNull(vAccelKeyboard, 0.0001)) vAccelKeyboard = normalize(vAccelKeyboard); if (!isNull(vAccelMouse, 0.0001)) vAccelMouse = normalize(vAccelMouse); // Scale the acceleration vector vAccelKeyboard *= mKeyboardMoveScaler; vAccelMouse *= mMouseMoveScaler; dvec3 vAccel = vAccelKeyboard + vAccelMouse; if( mMovementDrag ) { // Is there any acceleration this frame? if( length(vAccel) > 0.0 ) { // If so, then this means the user has pressed a movement key\ // so change the velocity immediately to acceleration // upon keyboard input. This isn't normal physics // but it will give a quick response to keyboard input mVelocity = vAccel; mDragTimer = mTotalDragTimeToZero; mVelocityDrag = vAccel / mDragTimer; } else { // If no key being pressed, then slowly decrease velocity to 0 if( mDragTimer > 0 ) { // Drag until timer is <= 0 mVelocity -= mVelocityDrag * fElapsedTime; mDragTimer -= fElapsedTime; } else { // Zero velocity mVelocity = vec3( 0, 0, 0 ); } } } else { // No drag, so immediately change the velocity mVelocity = vAccel; } }
dvec3 dvec3::cross(const dvec3& v) { double _x = y * v.z - z * v.y; double _y = z * v.x - x * v.z; double _z = x * v.y - y - v.x; return dvec3(_x, _y, _z); }
CameraView::CameraView() : m_transform( dquat(1.), dvec3(0.), 1. ) { m_parameters[eCP_FOV] = 55.0f; m_parameters[eCP_ASPECT] = 16.0f / 9.0f; m_parameters[eCP_NEAR] = 0.01f; m_parameters[eCP_FAR] = 100.0f; }
static dvec3 Vec3TransformCoord(dvec3 const & vector, dmat4 const & matrix) { const double x = vector.x * column(matrix, 0).x + vector.y * column(matrix, 1).x + vector.z * column(matrix, 2).x + column(matrix, 3).x; const double y = vector.x * column(matrix, 0).y + vector.y * column(matrix, 1).y + vector.z * column(matrix, 2).y + column(matrix, 3).y; const double z = vector.x * column(matrix, 0).z + vector.y * column(matrix, 1).z + vector.z * column(matrix, 2).z + column(matrix, 3).z; const double w = vector.x * column(matrix, 0).w + vector.y * column(matrix, 1).w + vector.z * column(matrix, 2).w + column(matrix, 3).w; return dvec3(x/w, y/w, z/w); }
//-------------------------------------------------------------------------------------- // Client can call this to change the position and direction of camera //-------------------------------------------------------------------------------------- void CBaseCamera::SetViewParams( dvec3 const & pvEyePt, dvec3 const & pvLookatPt ) { const dvec3 localEye = (mZAxisUp) ? dvec3(pvEyePt.x, pvEyePt.z, -pvEyePt.y) : pvEyePt; mDefaultEye = mEye = localEye; const dvec3 localLookAt = (mZAxisUp) ? dvec3(pvLookatPt.x, pvLookatPt.z, -pvLookatPt.y) : pvLookatPt; mDefaultLookAt = mLookAt = localLookAt; // Calc the view matrix const dvec3 vUp = dvec3( 0.0f ,1.0f,0.0f ); mViewMatrix = lookAt(localEye, localLookAt, vUp); dmat4 mInvView = inverse(mViewMatrix); // The axis basis vectors and camera position are stored inside the // position matrix in the 4 rows of the camera's world matrix. // To figure out the yaw/pitch of the camera, we just need the Z basis vector dvec3 pZBasis = MakeVec3(column(mInvView, 2)); mCameraYawAngle = atan2( pZBasis.x, pZBasis.z ); double fLen = sqrt(pZBasis.z * pZBasis.z + pZBasis.x * pZBasis.x); mCameraPitchAngle = -atan2( pZBasis.y, fLen ); }
PickingObject* PickingContainer::findPickingObject(const uvec2& coord){ if (pickingEnabled() && src_) { const Layer* pickingLayer = src_->getPickingLayer(); if (pickingLayer) { const LayerRAM* pickingLayerRAM = pickingLayer->getRepresentation<LayerRAM>(); dvec4 value = pickingLayerRAM->getValueAsVec4Double(coord); dvec3 pickedColor = (value.a > 0.0 ? value.rgb() : dvec3(0.0)); uvec3 color(pickedColor*255.0); return PickingManager::getPtr()->getPickingObjectFromColor(color); } } return nullptr; }
//-------------------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------------------- CBaseCamera::CBaseCamera() { mKeysDown = 0; mZAxisUp = false; ZeroMemory( mKeys, sizeof( BYTE ) * CAM_MAX_KEYS ); // Set attributes for the view matrix dvec3 vEyePt = dvec3( 0.0, 0.0, 0.0 ); dvec3 vLookatPt = dvec3( 0.0, 0.0, 1.0 ); // Setup the view matrix SetViewParams( vEyePt, vLookatPt ); // Setup the projection matrix SetProjParams( pi<double>() / 4, 1.0, 1.0, 1000.0 ); //GetCursorPos( &m_ptLastMousePosition ); mMouseLButtonDown = false; mMouseMButtonDown = false; mMouseRButtonDown = false; mCurrentButtonMask = 0; mMouseWheelDelta = 0; mCameraYawAngle = 0.0; mCameraPitchAngle = 0.0; //SetRect( &m_rcDrag, LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX ); mVelocity = dvec3( 0, 0, 0 ); mMovementDrag = false; mVelocityDrag = dvec3( 0, 0, 0 ); mDragTimer = 0.0f; mTotalDragTimeToZero = 0.25; mRotVelocity = dvec2( 0, 0 ); mRotationScaler = 0.01; mKeyboardMoveScaler = sKeyboardMovementScale; mMouseMoveScaler = sMouseMovementScale; mInvertPitch = false; mEnableYAxisMovement = true; mEnablePositionMovement = true; mMouseDelta = dvec2( 0, 0 ); mFramesToSmoothMouseData = 10.0f; mClipToBoundary = false; mMinBoundary = dvec3( -1, -1, -1 ); mMaxBoundary = dvec3( 1, 1, 1 ); mResetCursorAfterMove = false; mMouseRotates = true; }
int main(int argc, char * argv[]) { int n = 10323; std::vector<kdTree::Particle> ptcl; for (int i = 0; i < n; i++) ptcl.push_back(kdTree::Particle(i, dvec3(rand(-1,1), rand(-1,1), rand(-1,1)))); #if 0 kdTree kd(ptcl); #else kdTree kd; for (int i = 0; i < n; i++) kd.push_ptcl(ptcl[i]); kd.build(); #endif const double h = 0.2; const dvec3 pos(0.0,0.0,0.0); std::vector<int> list, list_n2; fprintf(stderr, "n_ngb= %d n2= %d\n", kd.range_search(list, pos, h), range_search_n2(list_n2, pos, h, ptcl) ); std::sort(list.begin(), list.end()); std::sort(list_n2.begin(), list_n2.end()); assert(list.size() == list_n2.size()); for (size_t i = 0; i < list.size(); i++) assert(list[i] == list_n2[i]); }
void Transform::RotateY(double angle) { m = rotate(m, angle, dvec3(0, 1, 0)); }
void Transform::RotateX(double angle) { m = rotate(m, angle, dvec3(1, 0, 0)); }
inline dvec3 cell_pos(const ivec3 &idx, const double d){ return d * (dvec3(0.5) + dvec3(idx)); }
void system::set_geometry(const bool init) { const double dt_max = 1.0/64 ; //16; // 1.0/128; scheduler = Scheduler(dt_max); t_end = 2.5; n_restart = 1; dt_restart = dt_max; dt_dump = dt_max / 16; dt_dump = dt_max ; //* 4; di_log = 100; global_n = local_n = 0; int nx = 16; int ny = 16; int nz = 16; // nx = ny = nz = 32; // nx = ny = nz = 64; nx = ny = 32; nz = 32; // nx = ny = 32; nz = 16; nx = ny = 64; nz = 16; nx = ny = 128; nz = 16; // nx = ny = 256; nz = 16; // nx = ny = 256; nz = 256; // nx = ny = nz = 128; // eulerian = true; #if 0 #if 1 #define __ADVECT_PULSE_TEST__ nx = ny = 64; nz = 16; dt_dump = dt_max; dt_restart = 1e10; #endif // nx = ny = 128; #endif const double Lx = 1.0; const vec3 rmin(0.0); const vec3 rmax(Lx, (Lx/nx)*ny, (Lx/nx)*nz); global_domain = boundary(rmin, rmax); global_domain_size = global_domain.hsize() * 2.0; const vec3 Len3 = global_domain.hsize() * 2.0; pfloat<0>::set_scale(Len3.x); pfloat<1>::set_scale(Len3.y); pfloat<2>::set_scale(Len3.z); Distribute::int3 nt(1, 1, 1); switch(nproc) { case 1: break; case 2: nt.x = 2; nt.y = 1; nt.z = 1; break; case 4: nt.x = 2; nt.y = 2; nt.z = 1; break; case 8: nt.x = 4; nt.y = 2; nt.z = 1; break; case 16: nt.x = 4; nt.y = 4; nt.z = 1; break; case 32: nt.x = 8; nt.y = 4; nt.z = 1; break; case 64: nt.x = 8; nt.y = 8; nt.z = 1; break; case 128: nt.x = 8; nt.y = 8; nt.z = 2; break; default: assert(false); } const Distribute::int3 nt_glb(nt); const pBoundary pglobal_domain(pfloat3(0.0), pfloat3(Len3)); distribute_glb.set(nproc, nt, pglobal_domain); if (!init) return; if (myproc == 0) { ptcl_local.clear(); ptcl_local.reserve(128); const dvec3 dr = dvec3(Len3.x/nx, Len3.y/ny, Len3.z/nz); const real rmax = dr.abs() * 1.0; fprintf(stderr, "dr= %g %g %g \n", dr.x, dr.y, dr.z); fprintf(stderr, "rmin= %g %g %g \n", global_domain.get_rmin().x, global_domain.get_rmin().y, global_domain.get_rmin().z); fprintf(stderr, "rmax= %g %g %g \n", global_domain.get_rmax().x, global_domain.get_rmax().y, global_domain.get_rmax().z); for (int k = 0; k < nz; k++) { for (int j = 0; j < ny; j++) { for (int i = 0; i < nx; i++) { dvec3 pos = global_domain.get_rmin() + dvec3(i*dr.x, j*dr.y, k*dr.z) + 0.5*dr; const int ijk = (k*ny + j)*nx + i; #if 0 if (!eulerian) { const real f = 1.0e-6; pos += vec3(drand48()*dr.x*f, drand48()*dr.y*f, drand48()*dr.z*f); } #endif #if 1 pos = global_domain.get_rmin() + dvec3( drand48()*Len3.x, drand48()*Len3.y, drand48()*Len3.z); #else #define _UNIFORM_MESH_ #endif dvec3 vel(0.0, 0.0, 0.0); Particle p; p.set_pos(pos); p.vel = vel; p.orig_vel = p.vel; p.boundary = 0; p.idx = ijk; p.rmax = rmax; ptcl_local.push_back(p); } } } local_n = ptcl_local.size(); global_n = local_n; fprintf(stderr, " *** proc= %d : local_n= %llu global_n= %llu \n", myproc, local_n, global_n); } // myproc == 0 MPI_Bcast(&global_n, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); if (myproc == 0) fprintf(stderr, " *** Distrubiting data \n"); all_active = true; for (int k = 0; k < 5; k++) distribute_data(false,false,false); #if 0 std::vector< std::pair<int, TREAL> > rmax_list; local_tree.root.get_rmax(rmax_list); assert((int)rmax_list.size() == local_n); for (int i = 0; i < local_n; i++) ptcl[rmax_list[i].first].rmax = rmax_list[i].second; #endif MPI_Barrier(MPI_COMM_WORLD); fprintf(stderr, " *** proc= %d : local_n= %llu global_n= %llu \n", myproc, local_n, global_n); fprintf(stderr, " proc= %d relax \n", myproc); #ifndef _UNIFORM_MESH_ relax_mesh(5); #endif fprintf(stderr, " ---- done --- \n"); { distribute_data(false, false, false); const double t10 = mytimer::get_wtime(); clear_mesh(false); int nattempt = build_mesh_global(); double dt10 = mytimer::get_wtime() - t10; double volume_loc = 0.0; { std::vector<TREAL> v(local_n); for (int i = 0; i < (int)local_n; i++) v[i] = cell_local[i].Volume; std::sort(v.begin(), v.end()); // sort volumes from low to high, to avoid roundoff errors for (int i = 0; i < (int)local_n; i++) volume_loc += v[i]; } double dt10max; MPI_Allreduce(&dt10, &dt10max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); double volume_glob = 0.0; int nattempt_max, nattempt_min; MPI_Allreduce(&volume_loc, &volume_glob, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(&nattempt, &nattempt_max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); MPI_Allreduce(&nattempt, &nattempt_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); const double volume_exact = global_domain_size.x*global_domain_size.y*global_domain_size.z; if (myproc == 0) { fprintf(stderr, "first call build_mesh:[ %g sec :: %g cells/s/proc/thread ]\n", dt10max, global_n/nproc/dt10max); fprintf(stderr, " computed_volume= %g exact_volume= %g diff= %g [ %g ] nattempt= %d %d \n", volume_glob, volume_exact, volume_glob - volume_exact, (volume_glob - volume_exact)/volume_exact, nattempt_min, nattempt_max); } } extract_ngb_from_mesh(); #if 0 set_problem(true); iterate(); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); exit(-1); #endif }
dvec3 dvec3::operator/(const dvec3& v) { return dvec3(x / v.x, y / v.y, z / v.z); }
dvec3 CFirstPersonCamera::GetWorldUp() const { const dvec3 worldUpYUp = MakeVec3(column(mCameraWorld, 1)); return (mZAxisUp) ? dvec3(worldUpYUp.x, -worldUpYUp.z, worldUpYUp.y) : worldUpYUp; }
void Transform::Translate(double x, double y, double z) { m = translate(m, dvec3(x, y, z)); }
glm::vec3 PathTracing::Radiance(const Ray& ray, Random *rnd, int depth) { Intersection isect; bool hit = this->scene_->Intersect(ray, &isect); if (!hit) { return BACKGROUND_COLOR; } const Primitive* p = isect.hitPrimitive_; const dvec3 orienting_normal = dot(isect.normal_, ray.direction_) < 0.0 ? isect.normal_ : -isect.normal_; // russian roulette // TODO: 確率しきい値は,色の反射率にする float russian_roulette_prob = glm::max(p->material_.color_.r, p->material_.color_.g, p->material_.color_.b); if (depth > MAX_DEPTH) { russian_roulette_prob *= pow(0.5, depth - MAX_DEPTH); } if (depth > MIN_DEPTH) { if (rnd->next() >= russian_roulette_prob) { return p->material_.emission_; } } else { russian_roulette_prob = 1.0f; // 強制的にMIN_DEPTH回は実行 } vec3 incoming_radiance; vec3 weight(1.0); switch (p->material_.reftype_) { case REFLECTION_TYPE_DIFFUSE: { // orienting_normalの方向を基準とした正規直交基底(w, u, v)を作る。この基底に対する半球内で次のレイを飛ばす。 glm::dvec3 w, u, v; w = orienting_normal; if (fabs(w.x) > Constants::EPS) // ベクトルwと直交するベクトルを作る。w.xが0に近い場合とそうでない場合とで使うベクトルを変える。 u = normalize(cross(dvec3(0.0, 1.0, 0.0), w)); else u = normalize(cross(dvec3(1.0, 0.0, 0.0), w)); v = cross(w, u); // コサイン項を使った重点的サンプリング const double r1 = 2 * M_PI * rnd->next(); const double r2 = rnd->next(), r2s = sqrt(r2); dvec3 dir = normalize(( u * cos(r1) * r2s + v * sin(r1) * r2s + w * sqrt(1.0 - r2))); incoming_radiance = Radiance(Ray(isect.position_, dir), rnd, depth+1); // レンダリング方程式に対するモンテカルロ積分を考えると、outgoing_radiance = weight * incoming_radiance。 // ここで、weight = (ρ/π) * cosθ / pdf(ω) / R になる。 // ρ/πは完全拡散面のBRDFでρは反射率、cosθはレンダリング方程式におけるコサイン項、pdf(ω)はサンプリング方向についての確率密度関数。 // Rはロシアンルーレットの確率。 // 今、コサイン項に比例した確率密度関数によるサンプリングを行っているため、pdf(ω) = cosθ/π // よって、weight = ρ/ R。 weight = p->material_.color_ / (float)russian_roulette_prob; } break; case REFLECTION_TYPE_SPECULAR: { // 完全鏡面なのでレイの反射方向は決定的。 // ロシアンルーレットの確率で除算するのは上と同じ。 incoming_radiance = Radiance(Ray(isect.position_, ray.direction_ - isect.normal_ * 2.0 * dot(isect.normal_, ray.direction_)), rnd, depth+1); weight = p->material_.color_ / russian_roulette_prob; } break; case REFLECTION_TYPE_REFRACTION: { const Ray reflection_ray = Ray(isect.position_, ray.direction_ - isect.normal_ * 2.0 * dot(isect.normal_, ray.direction_)); const bool into = dot(isect.normal_, orienting_normal) > 0.0; // レイがオブジェクトから出るのか、入るのか // Snellの法則 const double nc = 1.0; // 真空の屈折率 const double nt = p->material_.Ior_; // オブジェクトの屈折率 const double nnt = into ? nc / nt : nt / nc; const double ddn = dot(ray.direction_, orienting_normal); const double cos2t = 1.0 - nnt * nnt * (1.0 - ddn * ddn); if (cos2t < 0.0) { // 全反射 incoming_radiance = Radiance(reflection_ray, rnd, depth+1); weight = p->material_.color_ / (float)russian_roulette_prob; break; } // 屈折の方向 const Ray refraction_ray = Ray(isect.position_, normalize(ray.direction_ * nnt - isect.normal_ * (into ? 1.0 : -1.0) * (ddn * nnt + sqrt(cos2t)))); // SchlickによるFresnelの反射係数の近似を使う const double a = nt - nc, b = nt + nc; const double R0 = (a * a) / (b * b); const double c = 1.0 - (into ? -ddn : dot(refraction_ray.direction_, -1.0 * orienting_normal)); const double Re = R0 + (1.0 - R0) * pow(c, 5.0); // 反射方向の光が反射してray.dirの方向に運ぶ割合。同時に屈折方向の光が反射する方向に運ぶ割合。 const double nnt2 = pow(into ? nc / nt : nt / nc, 2.0); // レイの運ぶ放射輝度は屈折率の異なる物体間を移動するとき、屈折率の比の二乗の分だけ変化する。 const double Tr = (1.0 - Re) * nnt2; // 屈折方向の光が屈折してray.dirの方向に運ぶ割合 // 一定以上レイを追跡したら屈折と反射のどちらか一方を追跡する。(さもないと指数的にレイが増える) // ロシアンルーレットで決定する。 const double probability = 0.25 + 0.5 * Re; if (depth > 2) { if (rnd->next() < probability) { // 反射 incoming_radiance = Radiance(reflection_ray, rnd, depth+1) * (float)Re; weight = p->material_.color_ / (float)probability * russian_roulette_prob; } else { // 屈折 incoming_radiance = Radiance(refraction_ray, rnd, depth+1) * (float)Tr; weight = p->material_.color_ / (float)(1.0 - probability) * russian_roulette_prob; } } else { // 屈折と反射の両方を追跡 incoming_radiance = Radiance(reflection_ray, rnd, depth+1) * (float)Re + Radiance(refraction_ray, rnd, depth+1) * (float)Tr; weight = p->material_.color_ / (russian_roulette_prob); } } break; default: break; } return p->material_.emission_ + incoming_radiance * weight; }
dvec3 Origami::foldPoint(dvec2 ptOriginal) { dvec3 pt = dvec3(ptOriginal, 0); int vId = getAnyVertexInFace(ptOriginal); //int vId = 4; double angle, rad; int angleAt = getBiggestAngleLessThan(vId, ptOriginal); while (1) { { dvec2 ptRelV = dvec2(pt) - verts[vId].pt; angle = atan2(ptRelV.y, ptRelV.x); angle = rotClamp(angle); rad = length(ptRelV); } vertex& curV = verts[vId]; //int shiftSign = (foldAngleTree[vId] > angleAt) ? 1 : -1; int shiftSign = 1; int startAngle = angleAt + ((shiftSign > 0) ? 1 : 0); int endAngle = foldAngleTree[vId] + ((shiftSign > 0) ? 1 : 0); for (int i = startAngle; i % curV.numCreases() != endAngle % curV.numCreases(); i += shiftSign) { int correctedI = i % curV.numCreases(); pt = curV.fold(correctedI, pt, (shiftSign < 0) ? true : false); if (i == 0) i = curV.numCreases(); } if (vId == 0) break; assert(curV.bakedConnections.size() != 0); int newVert = curV.bakedConnections[foldAngleTree[vId]]; // find the new angleAt to preserve the rotation double angleToFind = rotClamp(curV.getAngle(foldAngleTree[vId]), PI); size_t i; bool found = false; for (i = 0; i < verts[newVert].numCreases(); ++i) { if (abs(angleToFind - verts[newVert].getAngle(i)) < epsilon) { found = true; break; } } if (!found) { printf("FOLD ERROR: The vertex pointed at by vertex %d and angle %d doesn't point back. Maybe insertCrease() to fix?\n", vId, angleAt); //insertWithRaycast(vId, curV.getAngle(foldAngleTree[vId]), curV.getSDihedral(foldAngleTree[vId])); //recompile(); } angleAt = (i - 1 + verts[newVert].numCreases()) % verts[newVert].numCreases(); vId = newVert; } return pt; }
dvec3 dvec3::normalize() { double len = 1.0f / length(); return dvec3(x * len, y * len, z * len); }
dvec3 dvec3::operator+(const dvec3& v) { return dvec3(x + v.x, y + v.y, z + v.z); }
dvec3 dvec3::operator-(const dvec3& v) { return dvec3(x - v.x, y - v.y, z - v.z); }
void Transform::RotateZ(double angle) { m = rotate(m, angle, dvec3(0, 0, 1)); }
dvec3 CFirstPersonCamera::GetWorldAhead() const { const dvec3 lookAtYUp = MakeVec3(column(mCameraWorld, 2)); return (mZAxisUp) ? dvec3(lookAtYUp.x, -lookAtYUp.z, lookAtYUp.y) : lookAtYUp; }
void Transform::Scale(double x, double y, double z) { m = scale(m, dvec3(x, y, z)); }
dvec3 CFirstPersonCamera::GetEyePt() const { const dvec3 eyeYUp = MakeVec3(column(mCameraWorld, 3)); return (mZAxisUp) ? dvec3(eyeYUp.x, -eyeYUp.z, eyeYUp.y) : eyeYUp; }
dvec3 DataFormatBase::valueToNormalizedVec3Double(void*) const { return dvec3(0.0); }
dvec3 dvec3::operator*(const dvec3& v) { return dvec3(x * v.x, y * v.y, z * v.z); }
//-------------------------------------------------------------------------------------- // Update the view matrix based on user input & elapsed time //-------------------------------------------------------------------------------------- void CFirstPersonCamera::FrameMove( double fElapsedTime ) { if( IsKeyDown( mKeys[CAM_RESET] ) ) { Reset(); } if (IsKeyDown(mKeys[CAM_ACCELERATE])) { if (mKeyboardMoveScaler < 10000.0) { mKeyboardMoveScaler *= 1.2; } if (mMouseMoveScaler < 10000.0) { mMouseMoveScaler *= 1.2; } //since accelerating shouldn't be done continously, force key up here HandleKeys(CAM_ACCELERATE, false); } if (IsKeyDown(mKeys[CAM_THROTTLE])) { if (mKeyboardMoveScaler > 0.1) { mKeyboardMoveScaler /= 1.2; } if (mMouseMoveScaler > 0.1) { mMouseMoveScaler /= 1.2; } HandleKeys(CAM_THROTTLE, false); } // Get keyboard/mouse/gamepad input GetInput( mEnablePositionMovement, ( mActiveButtonMask & mCurrentButtonMask ) || mRotateWithoutButtonDown, true, mResetCursorAfterMove ); // Get amount of velocity based on the keyboard input and drag (if any) UpdateVelocity( fElapsedTime ); // Simple euler method to calculate position delta dvec3 vPosDelta = mVelocity * fElapsedTime; // If rotating the camera if (mMouseRotates) { if( ( mActiveButtonMask & mCurrentButtonMask ) || mRotateWithoutButtonDown) { // Update the pitch & yaw angle based on mouse movement double fYawDelta = mRotVelocity.x; double fPitchDelta = mRotVelocity.y; // Invert pitch if requested if( mInvertPitch ) fPitchDelta = -fPitchDelta; mCameraPitchAngle -= fPitchDelta; mCameraYawAngle -= fYawDelta; // Limit pitch to straight up or straight down mCameraPitchAngle = std::max( -pi<double>() * 0.499, mCameraPitchAngle ); mCameraPitchAngle = std::min( +pi<double>() * 0.499, mCameraPitchAngle ); } } // Make a rotation matrix based on the camera's yaw & pitch dmat4 mCameraRot = yawPitchRoll(mCameraYawAngle, mCameraPitchAngle, 0.0); // Transform vectors based on camera's rotation matrix dvec3 vWorldUp, vWorldAhead; const dvec3 vLocalUp = dvec3( 0, 1, 0 ); const dvec3 vLocalAhead = dvec3( 0, 0, -1 ); vWorldUp = Vec3TransformCoord(vLocalUp, mCameraRot); vWorldAhead = Vec3TransformCoord(vLocalAhead, mCameraRot); // Transform the position delta by the camera's rotation dvec3 vPosDeltaWorld; if( !mEnableYAxisMovement ) { // If restricting Y movement, do not include pitch // when transforming position delta vector. mCameraRot = yawPitchRoll(mCameraYawAngle, 0.0, 0.0 ); } vPosDeltaWorld = Vec3TransformCoord(vPosDelta, mCameraRot ); // Move the eye position mEye += vPosDeltaWorld; if( mClipToBoundary ) ConstrainToBoundary( &mEye ); // Update the lookAt position based on the eye position mLookAt = mEye + vWorldAhead; // Update the view matrix mViewMatrix = lookAt(mEye, mLookAt, vWorldUp ); mCameraWorld = inverse(mViewMatrix ); }
void system::set_geometry(const bool init) { const double dt_max = 1.0/512; scheduler = Scheduler(dt_max); int np; float lx, ly, lz; FILE *fin = NULL; if (myproc == 0) { float wp; fin = fopen(fin_data, "r"); int ival; size_t nread; nread = fread(&ival, sizeof(int), 1, fin); assert(ival == 2*sizeof(int)); nread = fread(&np, sizeof(int), 1, fin); nread = fread(&wp, sizeof(float), 1, fin); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == 2*sizeof(int)); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == 3*sizeof(float)); nread = fread(&lx, sizeof(float), 1, fin); nread = fread(&ly, sizeof(float), 1, fin); nread = fread(&lz, sizeof(float), 1, fin); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == 3*sizeof(float)); fprintf(stderr, " np= %d wp= %g \n",np, wp); fprintf(stderr, " lx= %g ly= %g lz= %g \n", lx, ly, lz); } MPI_Bcast(&lx, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(&ly, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(&lz, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); t_end = 0.2; n_restart = 2; dt_restart = dt_max; dt_dump = 0.01; di_log = 100; global_n = local_n = 0; // eulerian = true; const vec3 rmin(0.0); const vec3 rmax(lx, ly, lz); global_domain = boundary(rmin, rmax); global_domain_size = global_domain.hsize() * 2.0; const vec3 Len3 = global_domain.hsize() * 2.0; pfloat<0>::set_scale(Len3.x); pfloat<1>::set_scale(Len3.y); pfloat<2>::set_scale(Len3.z); if (myproc == 0) { ptcl.resize(np); const int nx = (int)std::pow(np, 1.0/3.0); const dvec3 dr = dvec3(Len3.x/nx, Len3.y/nx, Len3.z/nx); const real rmax = dr.abs() * 1.0; fprintf(stderr, "dr= %g %g %g \n", dr.x, dr.y, dr.z); local_n = ptcl.size(); global_n = local_n; { std::vector<float> x(local_n), y(local_n), z(local_n); size_t nread; int ival; nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&x[0], sizeof(float), local_n, fin); assert((int)nread == local_n); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&y[0], sizeof(float), local_n, fin); assert((int)nread == local_n); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&z[0], sizeof(float), local_n, fin); assert((int)nread == local_n); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); for (int i = 0; i < local_n; i++) { const dvec3 vel(0.0, 0.0, 0.0); ptcl[i] = Particle(x[i], y[i], z[i], vel.x, vel.y, vel.z, i); ptcl[i].rmax = rmax; ptcl[i].unset_derefine(); } } U.resize(local_n); const int var_list[7] = { Fluid::VELX, Fluid::VELY, Fluid::VELZ, Fluid::DENS, Fluid::BX, Fluid::BY, Fluid::BZ}; std::vector<float> data(local_n); for (int var = 0; var < 7; var++) { fprintf(stderr, " reading vat %d out of %d \n", var+1, 7); int ival; size_t nread; nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); nread = fread(&data[0], sizeof(float), local_n, fin); assert((int)nread == local_n); nread = fread(&ival, sizeof(int), 1, fin); assert(ival == local_n*(int)sizeof(float)); for (int i = 0; i < local_n; i++) U[i][var_list[var]] = data[i]; } for (int i = 0; i < local_n; i++) { assert(U[i][Fluid::DENS] > 0.0); U[i][Fluid::ETHM] = cs2 * U[i][Fluid::DENS]; } fclose(fin); fprintf(stderr, " *** proc= %d : local_n= %d global_n= %d \n", myproc, local_n, global_n); } // myproc == 0 MPI_Bcast(&global_n, 1, MPI_INT, 0, MPI_COMM_WORLD); fprintf(stderr, " proc= %d distrubite \n", myproc); MPI_Barrier(MPI_COMM_WORLD); Distribute::int3 nt(1, 1, 1); switch(nproc) { case 1: break; case 2: nt.x = 2; nt.y = 1; nt.z = 1; break; case 4: nt.x = 2; nt.y = 2; nt.z = 1; break; case 6: nt.x = 3; nt.y = 2; nt.z = 1; break; case 8: nt.x = 2; nt.y = 2; nt.z = 2; break; case 16: nt.x = 4; nt.y = 2; nt.z = 2; break; case 32: nt.x = 4; nt.y = 4; nt.z = 2; break; case 64: nt.x = 4; nt.y = 4; nt.z = 4; break; case 128: nt.x = 8; nt.y = 4; nt.z = 4; break; case 256: nt.x = 8; nt.y = 8; nt.z = 4; break; case 512: nt.x = 8; nt.y = 8; nt.z = 8; break; default: assert(false); } const Distribute::int3 nt_glb(nt); const pBoundary pglobal_domain(pfloat3(0.0), pfloat3(Len3)); distribute_glb.set(nproc, nt, pglobal_domain); for (int k = 0; k < 5; k++) distribute_data(true, false); const int nloc_reserve = (int)(2.0*global_n/nproc); fit_reserve_vec(ptcl, nloc_reserve); fit_reserve_vec(ptcl_ppos, nloc_reserve); fit_reserve_vec(U, nloc_reserve); fit_reserve_vec(dU, nloc_reserve); fit_reserve_vec(Wgrad, nloc_reserve); fit_reserve_vec(gradPsi, nloc_reserve); fit_reserve_vec(cells, nloc_reserve); MPI_Barrier(MPI_COMM_WORLD); fprintf(stderr, " *** proc= %d : local_n= %d global_n= %d \n", myproc, local_n, global_n); fprintf(stderr, " proc= %d building_mesh \n", myproc); MPI_Barrier(MPI_COMM_WORLD); const double t10 = mytimer::get_wtime(); clear_mesh(); int nattempt = build_mesh(true); double dt10 = mytimer::get_wtime() - t10; double volume_loc = 0.0; { std::vector<TREAL> v(local_n); for (int i = 0; i < local_n; i++) v[i] = cells[i].Volume; std::sort(v.begin(), v.end()); // sort volumes from low to high, to avoid roundoff errors for (int i = 0; i < local_n; i++) volume_loc += v[i]; } double dt10max; MPI_Allreduce(&dt10, &dt10max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); double volume_glob = 0.0; int nattempt_max, nattempt_min; MPI_Allreduce(&volume_loc, &volume_glob, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(&nattempt, &nattempt_max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); MPI_Allreduce(&nattempt, &nattempt_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); const double volume_exact = global_domain_size.x*global_domain_size.y*global_domain_size.z; if (myproc == 0) { fprintf(stderr, "first call build_mesh:[ %g sec :: %g cells/s/proc/thread ]\n", dt10max, global_n/nproc/dt10max); fprintf(stderr, " computed_volume= %g exact_volume= %g diff= %g [ %g ] nattempt= %d %d \n", volume_glob, volume_exact, volume_glob - volume_exact, (volume_glob - volume_exact)/volume_exact, nattempt_min, nattempt_max); } exchange_ptcl(); }