/*===========================================================================*/ bool CellBase::containsLocalPoint( const kvs::Vec3& local ) const { if ( local.x() < 0 || 1 < local.x() ) { return false; } if ( local.y() < 0 || 1 < local.y() ) { return false; } if ( local.z() < 0 || 1 < local.z() ) { return false; } return true; }
/*===========================================================================*/ bool TetrahedralCell::containsLocalPoint( const kvs::Vec3& local ) const { if ( local.x() < 0 || 1 < local.x() ) { return false; } if ( local.y() < 0 || 1 < local.y() ) { return false; } if ( local.z() < 0 || 1 < local.z() ) { return false; } if ( local.x() + local.y() + local.z() > 1 ) { return false; } return true; }
/*===========================================================================*/ kvs::Vec3 TetrahedralCell::globalPoint() const { const kvs::Vec3 v3( BaseClass::coord(3) ); const kvs::Vec3 v03( BaseClass::coord(0) - v3 ); const kvs::Vec3 v13( BaseClass::coord(1) - v3 ); const kvs::Vec3 v23( BaseClass::coord(2) - v3 ); const kvs::Mat3 M( v03.x(), v13.x(), v23.x(), v03.y(), v13.y(), v23.y(), v03.z(), v13.z(), v23.z() ); return M * BaseClass::localPoint() + v3; }
/*===========================================================================*/ kvs::Vec3 TetrahedralCell::globalToLocal( const kvs::Vec3& global ) const { const kvs::Vec3 v3( BaseClass::coord(3) ); const kvs::Vec3 v03( BaseClass::coord(0) - v3 ); const kvs::Vec3 v13( BaseClass::coord(1) - v3 ); const kvs::Vec3 v23( BaseClass::coord(2) - v3 ); const kvs::Mat3 M( v03.x(), v13.x(), v23.x(), v03.y(), v13.y(), v23.y(), v03.z(), v13.z(), v23.z() ); return M.inverted() * ( global - v3 ); }
void TextEngine::draw( const kvs::Vec3& p, const std::string& text, kvs::ScreenBase* screen ) const { GLdouble model[16]; kvs::OpenGL::GetModelViewMatrix( model ); GLdouble proj[16]; kvs::OpenGL::GetProjectionMatrix( proj ); GLint view[4]; kvs::OpenGL::GetViewport( view ); GLdouble winx = 0, winy = 0, winz = 0; kvs::OpenGL::Project( p.x(), p.y(), p.z(), model, proj, view, &winx, &winy, &winz ); kvs::OpenGL::WithPushedAttrib attrib( GL_ALL_ATTRIB_BITS ); attrib.disable( GL_TEXTURE_1D ); attrib.disable( GL_TEXTURE_2D ); // attrib.enable( GL_TEXTURE_2D ); attrib.disable( GL_TEXTURE_3D ); attrib.enable( GL_DEPTH_TEST ); attrib.enable( GL_BLEND ); { kvs::OpenGL::SetBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); kvs::OpenGL::WithPushedMatrix modelview( GL_MODELVIEW ); modelview.loadIdentity(); { kvs::OpenGL::WithPushedMatrix projection( GL_PROJECTION ); projection.loadIdentity(); { const GLint left = view[0]; const GLint top = view[1]; const GLint right = view[0] + view[2]; const GLint bottom = view[1] + view[3]; kvs::OpenGL::SetOrtho( left, right, bottom, top, 0, 1 ); kvs::OpenGL::Translate( 0, 0, -winz ); m_font.draw( kvs::Vec2( winx, top - ( winy - bottom ) ), text ); } } } }
/*===========================================================================*/ const kvs::Vec3 Quaternion::Rotate( const kvs::Vec3& pos, const kvs::Quaternion& q ) { const Quaternion p( pos.x(), pos.y(), pos.z(), 0.0f ); const Quaternion rotate_conj = q.conjugated(); const Quaternion rotate_pos = q * p * rotate_conj; return rotate_pos.m_elements.xyz(); }
/*===========================================================================*/ bool StreamlineBase::check_for_inside_volume( const kvs::Vec3& point ) { switch ( BaseClass::volume()->volumeType() ) { case kvs::VolumeObjectBase::Structured: { const kvs::StructuredVolumeObject* structured_volume = kvs::StructuredVolumeObject::DownCast( BaseClass::volume() ); switch ( structured_volume->gridType() ) { case kvs::StructuredVolumeObject::Uniform: { const float dimx = static_cast<float>( structured_volume->resolution().x() - 1 ); const float dimy = static_cast<float>( structured_volume->resolution().y() - 1 ); const float dimz = static_cast<float>( structured_volume->resolution().z() - 1 ); if ( point.x() < 0.0f || dimx < point.x() ) return false; if ( point.y() < 0.0f || dimy < point.y() ) return false; if ( point.z() < 0.0f || dimz < point.z() ) return false; return true; } case kvs::StructuredVolumeObject::Rectilinear: { const kvs::Vec3& min_obj = structured_volume->minObjectCoord(); const kvs::Vec3& max_obj = structured_volume->maxObjectCoord(); if ( point.x() < min_obj.x() || max_obj.x() < point.x() ) return false; if ( point.y() < min_obj.y() || max_obj.y() < point.y() ) return false; if ( point.z() < min_obj.z() || max_obj.z() < point.z() ) return false; return true; } default: break; } break; } default: break; } return false; }
/*===========================================================================*/ const Quaternion Quaternion::RotationQuaternion( kvs::Vec3 v0, kvs::Vec3 v1 ) { Quaternion q; v0.normalize(); v1.normalize(); kvs::Vec3 c = v0.cross( v1 ); float d = v0.x() * v1.x() + v0.y() * v1.y() + v0.z() * v1.z(); double s = std::sqrt( double( ( 1 + d ) * 2.0 ) ); q.x() = float( c.x() / s ); q.y() = float( c.y() / s ); q.z() = float( c.z() / s ); q.w() = float( s / 2.0 ); return q; }
/*===========================================================================*/ const kvs::Vec3 Quaternion::Rotate( const kvs::Vec3& pos, const kvs::Vec3& axis, float rad ) { const Quaternion p( pos.x(), pos.y(), pos.z(), 0.0f ); const Quaternion rotate_quat( axis, rad ); const Quaternion rotate_conj = rotate_quat.conjugated(); const Quaternion rotate_pos = rotate_quat * p * rotate_conj; return rotate_pos.m_elements.xyz(); }
/*===========================================================================*/ bool CellBase::containsInBounds( const kvs::Vec3& global ) const { kvs::Vec3 min_coord = this->coords()[0]; kvs::Vec3 max_coord = this->coords()[0]; const size_t nnodes = this->numberOfCellNodes(); for ( size_t i = 0; i < nnodes; i++ ) { const kvs::Vec3 v = this->coords()[i]; min_coord.x() = kvs::Math::Min( min_coord.x(), v.x() ); min_coord.y() = kvs::Math::Min( min_coord.y(), v.y() ); min_coord.z() = kvs::Math::Min( min_coord.z(), v.z() ); max_coord.x() = kvs::Math::Max( max_coord.x(), v.x() ); max_coord.y() = kvs::Math::Max( max_coord.y(), v.y() ); max_coord.z() = kvs::Math::Max( max_coord.z(), v.z() ); } if ( global.x() < min_coord.x() || global.x() > max_coord.x() ) { return false; } if ( global.y() < min_coord.y() || global.y() > max_coord.y() ) { return false; } if ( global.z() < min_coord.z() || global.z() > max_coord.z() ) { return false; } return true; }
/*==========================================================================*/ void QuadraticTetrahedralCell::updateDifferentialFunctions( const kvs::Vec3& local ) const { KVS_ASSERT( BaseClass::containsLocalPoint( local ) ); const float p = local.x(); const float q = local.y(); const float r = local.z(); const float w = 1 - p - q - r; const size_t nnodes = BaseClass::numberOfCellNodes(); kvs::Real32* dN = BaseClass::differentialFunctions(); kvs::Real32* dNdp = dN; kvs::Real32* dNdq = dNdp + nnodes; kvs::Real32* dNdr = dNdq + nnodes; // dNdp dNdp[0] = -4 * w + 1; dNdp[1] = 4 * p - 1; dNdp[2] = 0; dNdp[3] = 0; dNdp[4] = 4 * (w - p); dNdp[5] = -4 * r; dNdp[6] = -4 * q; dNdp[7] = 4 * r; dNdp[8] = 0; dNdp[9] = 4 * q; // dNdq dNdq[0] = -4 * w + 1; dNdq[1] = 0; dNdq[2] = 0; dNdq[3] = 4 * q - 1; dNdq[4] = -4 * p; dNdq[5] = -4 * r; dNdq[6] = 4 * (w - q); dNdq[7] = 0; dNdq[8] = 4 * r; dNdq[9] = 4 * p; // dNdr dNdr[0] = -4 * w + 1; dNdr[1] = 0; dNdr[2] = 4 * r - 1; dNdr[3] = 0; dNdr[4] = -4 * p; dNdr[5] = 4 * (w - r); dNdr[6] = -4 * q; dNdr[7] = 4 * p; dNdr[8] = 4 * q; dNdr[9] = 0; }
/*==========================================================================*/ void TetrahedralCell::updateInterpolationFunctions( const kvs::Vec3& local ) const { KVS_ASSERT( this->containsLocalPoint( local ) ); const float p = local.x(); const float q = local.y(); const float r = local.z(); kvs::Real32* N = BaseClass::interpolationFunctions(); N[0] = p; N[1] = q; N[2] = r; N[3] = 1.0f - p - q - r; }
void GridBase::updateDifferentialFunctions( const kvs::Vec3& local ) { const float p = local.x(); const float q = local.y(); const float r = local.z(); const float pq = p * q; const float qr = q * r; const float rp = r * p; const size_t nnodes = m_nnodes; kvs::Real32* dN = m_differential_functions; kvs::Real32* dNdp = dN; kvs::Real32* dNdq = dNdp + nnodes; kvs::Real32* dNdr = dNdq + nnodes; dNdp[0] = - 1.0f + q +r - qr; dNdp[1] = 1.0f - q - r + qr; dNdp[2] = q - qr; dNdp[3] = - q + qr; dNdp[4] = - r + qr; dNdp[5] = r - qr; dNdp[6] = qr; dNdp[7] = - qr; dNdq[0] = - 1.0f + p + r - rp; dNdq[1] = - p + rp; dNdq[2] = p - rp; dNdq[3] = 1.0f - p - r + rp; dNdq[4] = - r + rp; dNdq[5] = - rp; dNdq[6] = rp; dNdq[7] = r - rp; dNdr[0] = - 1.0f + q + p - pq; dNdr[1] = - p + pq; dNdr[2] = - pq; dNdr[3] = - q + pq; dNdr[4] = 1.0f - q - p + pq; dNdr[5] = p - pq; dNdr[6] = pq; dNdr[7] = q - pq; }
kvs::Mat3 PrismCell::localGradient() { const kvs::Real32 p = m_local.x(); const kvs::Real32 q = m_local.y(); const kvs::Real32 r = m_local.z(); KVS_ASSERT( 0.0f <= p && p <= 1.0f ); KVS_ASSERT( 0.0f <= q && q <= 1.0f ); KVS_ASSERT( 0.0f <= r && r <= 1.0f ); KVS_ASSERT( p + q <= 1.0f ); const kvs::Vec3 v02 = ::Mix( this->value(0), this->value(2), q ); const kvs::Vec3 v35 = ::Mix( this->value(3), this->value(5), q ); const kvs::Vec3 v12 = ::Mix( this->value(1), this->value(2), q ); const kvs::Vec3 v45 = ::Mix( this->value(4), this->value(5), q ); const kvs::Vec3 x0 = ::Mix( v02, v35, r ); const kvs::Vec3 x1 = ::Mix( v12, v45, r ); const kvs::Vec3 v01 = ::Mix( this->value(0), this->value(1), p ); const kvs::Vec3 v34 = ::Mix( this->value(3), this->value(4), p ); const kvs::Vec3 v21 = ::Mix( this->value(2), this->value(1), p ); const kvs::Vec3 v54 = ::Mix( this->value(5), this->value(4), p ); const kvs::Vec3 y0 = ::Mix( v01, v34, r ); const kvs::Vec3 y1 = ::Mix( v21, v54, r ); const kvs::Real32 ratio = kvs::Math::IsZero( 1 - q ) ? 0.0f : p / ( 1 - q ); const kvs::Vec3 z0 = ::Mix( v02, v12, ratio ); const kvs::Vec3 z1 = ::Mix( v35, v45, ratio ); const kvs::Real32 dx = 1 - q; const kvs::Real32 dy = 1 - p; const kvs::Real32 dz = 1; const kvs::Real32 dudx = ( x1.x() - x0.x() ) / dx; const kvs::Real32 dudy = ( y1.x() - y0.x() ) / dy; const kvs::Real32 dudz = ( z1.x() - z0.x() ) / dz; const kvs::Real32 dvdx = ( x1.y() - x0.y() ) / dx; const kvs::Real32 dvdy = ( y1.y() - y0.y() ) / dy; const kvs::Real32 dvdz = ( z1.y() - z0.y() ) / dz; const kvs::Real32 dwdx = ( x1.z() - x0.z() ) / dx; const kvs::Real32 dwdy = ( y1.z() - y0.z() ) / dy; const kvs::Real32 dwdz = ( z1.z() - z0.z() ) / dz; return kvs::Mat3( dudx, dvdx, dwdx, dudy, dvdy, dwdy, dudz, dvdz, dwdz ); }
/*==========================================================================*/ void QuadraticTetrahedralCell::updateInterpolationFunctions( const kvs::Vec3& local ) const { KVS_ASSERT( BaseClass::containsLocalPoint( local ) ); const float p = local.x(); const float q = local.y(); const float r = local.z(); const float w = 1 - p - q - r; kvs::Real32* N = BaseClass::interpolationFunctions(); N[0] = w * (2 * w - 1); // (0, 0, 0) N[1] = p * (2 * p - 1); // (1, 0, 0) N[2] = r * (2 * r - 1); // (0, 0, 1) N[3] = q * (2 * q - 1); // (0, 1, 0) N[4] = 4 * p * w; // (1/2, 0, 0) N[5] = 4 * r * w; // ( 0, 0, 1/2) N[6] = 4 * q * w; // ( 0, 1/2, 0) N[7] = 4 * r * p; // (1/2, 0, 1/2) N[8] = 4 * q * r; // ( 0, 1/2, 1/2) N[9] = 4 * p * q; // (1/2, 1/2, 0) }
void GridBase::updateInterpolationFunctions( const kvs::Vec3& local ) { const float p = local.x(); const float q = local.y(); const float r = local.z(); const float pq = p * q; const float qr = q * r; const float rp = r * p; const float pqr = pq * r; kvs::Real32* N = m_interpolation_functions; N[0] = 1.0f - p - q - r + pq + qr + rp - pqr; N[1] = p - pq - rp + pqr; N[2] = pq - pqr; N[3] = q - pq - qr + pqr; N[4] = r - rp - qr + pqr; N[5] = rp - pqr; N[6] = pqr; N[7] = qr - pqr; }
/*===========================================================================*/ bool StreamlineBase::calculate_one_side( std::vector<kvs::Real32>* coords, std::vector<kvs::UInt8>* colors, const kvs::Vec3& seed_point, const kvs::Vec3& seed_vector ) { // Register the seed point. kvs::Vec3 current_vertex = seed_point; kvs::Vec3 next_vertex = seed_point; coords->push_back( seed_point.x() ); coords->push_back( seed_point.y() ); coords->push_back( seed_point.z() ); // Register the vector on the seed point. kvs::Vec3 current_vector = seed_vector; kvs::Vec3 previous_vector = seed_vector; // Set the color of seed point. kvs::RGBColor col = this->calculate_color( current_vector ); colors->push_back( col.r() ); colors->push_back( col.g() ); colors->push_back( col.b() ); size_t integral_times = 0; for ( ; ; ) { // Calculate the next vertex. if ( !this->calculate_next_vertex( current_vertex, current_vector, &next_vertex ) ) { return true; } // Check the termination. if ( this->check_for_termination( current_vertex, current_vector, integral_times, next_vertex ) ) { return true; } // Update the vertex and vector. current_vertex = next_vertex; previous_vector = current_vector; coords->push_back( current_vertex.x() ); coords->push_back( current_vertex.y() ); coords->push_back( current_vertex.z() ); // Interpolate vector from vertex of cell. current_vector = this->interpolate_vector( current_vertex, previous_vector ); // Set color of vertex. kvs::RGBColor col = this->calculate_color( current_vector ); colors->push_back( col.r() ); colors->push_back( col.g() ); colors->push_back( col.b() ); integral_times++; } }
/*===========================================================================*/ const kvs::Vec3 Streamline::interpolate_vector( const kvs::Vec3& vertex, const kvs::Vec3& previous_vector ) { kvs::IgnoreUnusedVariable( previous_vector ); const size_t cell_x = static_cast<size_t>( vertex.x() ); const size_t cell_y = static_cast<size_t>( vertex.y() ); const size_t cell_z = static_cast<size_t>( vertex.z() ); const kvs::StructuredVolumeObject* volume = kvs::StructuredVolumeObject::DownCast( BaseClass::volume() ); const size_t resolution_x = static_cast<size_t>( volume->resolution().x() ); const size_t resolution_y = static_cast<size_t>( volume->resolution().y() ); // const size_t resolution_z = static_cast<size_t>( volume->resolution().z() ); size_t vertex_id[8]; vertex_id[0] = cell_z * resolution_x * resolution_y + cell_y * resolution_x + cell_x; vertex_id[1] = vertex_id[0] + 1; vertex_id[2] = vertex_id[1] + resolution_x; vertex_id[3] = vertex_id[2] - 1; vertex_id[4] = vertex_id[0] + resolution_x * resolution_y; vertex_id[5] = vertex_id[4] + 1; vertex_id[6] = vertex_id[5] + resolution_x; vertex_id[7] = vertex_id[6] - 1; // Weight. const kvs::Vec3 local_coord( 2.0f * ( vertex.x() - cell_x ) - 1.0f, 2.0f * ( vertex.y() - cell_y ) - 1.0f, 2.0f * ( vertex.z() - cell_z ) - 1.0f ); const float x_min = local_coord.x() - 1.0f; const float x_max = local_coord.x() + 1.0f; const float y_min = local_coord.y() - 1.0f; const float y_max = local_coord.y() + 1.0f; const float z_min = local_coord.z() - 1.0f; const float z_max = local_coord.z() + 1.0f; const float weight[8] = { -x_min * y_min * z_min * 0.125f, x_max * y_min * z_min * 0.125f, -x_max * y_max * z_min * 0.125f, x_min * y_max * z_min * 0.125f, x_min * y_min * z_max * 0.125f, -x_max * y_min * z_max * 0.125f, x_max * y_max * z_max * 0.125f, -x_min * y_max * z_max * 0.125f }; // Interpolate. const std::type_info& type = BaseClass::volume()->values().typeInfo()->type(); if ( type == typeid( kvs::Int8 ) ) return ::GetInterpolatedVector<kvs::Int8>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::Int16 ) ) return ::GetInterpolatedVector<kvs::Int16>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::Int32 ) ) return ::GetInterpolatedVector<kvs::Int32>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::Int64 ) ) return ::GetInterpolatedVector<kvs::Int64>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::UInt8 ) ) return ::GetInterpolatedVector<kvs::UInt8>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::UInt16 ) ) return ::GetInterpolatedVector<kvs::UInt16>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::UInt32 ) ) return ::GetInterpolatedVector<kvs::UInt32>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::UInt64 ) ) return ::GetInterpolatedVector<kvs::UInt64>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::Real32 ) ) return ::GetInterpolatedVector<kvs::Real32>( vertex_id, weight, BaseClass::volume() ); else if ( type == typeid( kvs::Real64 ) ) return ::GetInterpolatedVector<kvs::Real64>( vertex_id, weight, BaseClass::volume() ); return kvs::Vec3( 0.0f, 0.0f, 0.0f ); }