Exemple #1
0
// ---------------------------------------------------------------------------------
// calculate vertex normals given the triangles
void 
Mesh3D::
calculateVertexNormals()
{
	// create 0-normals
	m_vertexNormals = std::vector< Vector3 >( getNumberOfVertices(), Vector3(0,0,0) );

	for(unsigned int i = 0; i < getNumberOfFaces(); i++) {
		int v1 = getFaceVertexIndex(i,0);
		int v2 = getFaceVertexIndex(i,1);
		int v3 = getFaceVertexIndex(i,2);

		assert( v1 < getNumberOfVertices() );
		assert( v2 < getNumberOfVertices() );
		assert( v3 < getNumberOfVertices() );

		Vector3 p = getVertexPosition( v1 );
		Vector3 q = getVertexPosition( v2 );
		Vector3 r = getVertexPosition( v3 );
		Vector3 n = (q-p).cross(r-p).normalize();

		m_vertexNormals[v1] += n;
		m_vertexNormals[v2] += n;
		m_vertexNormals[v3] += n;
	}

	for(int i = 0; i < getNumberOfVertices(); i++) {
		assert( m_vertexNormals[i].length() > 0 );
		m_vertexNormals[i] = m_vertexNormals[i].normalize();
	}

}
Exemple #2
0
Math::Vector3d Path::getWeightedPositionInEdge(uint edgeIndex, float positionInEdge) {
	float edgeLength = getEdgeLength(edgeIndex);
	float weightedEdgeLength = getWeightedEdgeLength(edgeIndex);

	float startWeight = getVertexWeight(edgeIndex);
	float endWeight = getVertexWeight(edgeIndex + 1);

	float weightedEdgePosition = ((endWeight - startWeight) / (2 * weightedEdgeLength) * positionInEdge + startWeight) * 0.001
	      * positionInEdge / edgeLength;

	Math::Vector3d edgeStart = getVertexPosition(edgeIndex);
	Math::Vector3d edgeEnd = getVertexPosition(edgeIndex + 1);

	return edgeEnd * weightedEdgePosition + edgeStart * (1.0 - weightedEdgePosition);
}
Exemple #3
0
Triangle Terrain::getTriangle( const QPointF & position ) const
{
	QPoint pos = QPoint( position.x(), position.y() );

	if( pos.x() >= mMapSize.width()-1 )
		pos.setX( mMapSize.width()-2 );
	if( pos.y() >= mMapSize.height()-1 )
		pos.setY( mMapSize.height()-2 );
	if( pos.x() < 0 )
		pos.setX( 0 );
	if( pos.y() < 0 )
		pos.setY( 0 );

	QPointF fraction = QPointF( position.x()-(float)pos.x(), position.y()-(float)pos.y() );
	if( fraction.x() + fraction.y() < 1.0f )
	{
		return Triangle(
			getVertexPosition( pos.x(), pos.y() ),
			getVertexPosition( pos.x(), pos.y()+1 ),
			getVertexPosition( pos.x()+1, pos.y() )
		);
	}
	return Triangle(
		getVertexPosition( pos.x()+1, pos.y()+1 ),
		getVertexPosition( pos.x()+1, pos.y() ),
		getVertexPosition( pos.x(), pos.y()+1 )
	);
}
Exemple #4
0
bool Terrain::getLineQuadIntersection( const QVector3D & origin, const QVector3D & direction, const QPoint & quadMapCoord, float & length ) const
{
	QPoint pos = quadMapCoord;
	if( pos.x() >= mMapSize.width()-1 )
		pos.setX( mMapSize.width()-2 );
	if( pos.y() >= mMapSize.height()-1 )
		pos.setY( mMapSize.height()-2 );
	if( pos.x() < 0 )
		pos.setX( 0 );
	if( pos.y() < 0 )
		pos.setY( 0 );

	float intersectionDistance;

	Triangle t1(
		getVertexPosition( pos.x(), pos.y() ),
		getVertexPosition( pos.x(), pos.y()+1 ),
		getVertexPosition( pos.x()+1, pos.y() )
	);

	if( t1.intersectRay( origin, direction, &intersectionDistance ) )
	{
		if( intersectionDistance < length && intersectionDistance > 0.0f )
		{
			length = intersectionDistance;
			return true;
		}
	}

	Triangle t2(
		getVertexPosition( pos.x()+1, pos.y()+1 ),
		getVertexPosition( pos.x()+1, pos.y() ),
		getVertexPosition( pos.x(), pos.y()+1 )
	);

	if( t2.intersectRay( origin, direction, &intersectionDistance ) )
	{
		if( intersectionDistance < length && intersectionDistance > 0.0f )
		{
			length = intersectionDistance;
			return true;
		}
	}

	return false;
}
Exemple #5
0
bool Terrain::getTriangle( const QPointF & position, Triangle & t ) const
{
	QPoint pos = QPoint( position.x(), position.y() );

	if( pos.x() >= mMapSize.width()-1 || pos.y() >= mMapSize.height()-1 || pos.x() < 0 || pos.y() < 0 )
		return false;

	QPointF fraction = QPointF( position.x()-(float)pos.x(), position.y()-(float)pos.y() );

	if( fraction.x() + fraction.y() < 1.0f )
	{
		t.setP( getVertexPosition( pos.x(), pos.y() ) );
		t.setQ( getVertexPosition( pos.x(), pos.y()+1 ) );
		t.setR( getVertexPosition( pos.x()+1, pos.y() ) );
	} else {
		t.setP( getVertexPosition( pos.x()+1, pos.y()+1 ) );
		t.setQ( getVertexPosition( pos.x()+1, pos.y() ) );
		t.setR( getVertexPosition( pos.x(), pos.y()+1 ) );
	}

	return true;
}
Exemple #6
0
float Path::getEdgeLength(uint edgeIndex) const {
	Math::Vector3d edgeStart = getVertexPosition(edgeIndex);
	Math::Vector3d edgeEnd = getVertexPosition(edgeIndex + 1);

	return edgeStart.getDistanceTo(edgeEnd);
}
Exemple #7
0
Math::Vector3d Path3D::getEdgeDirection(uint edgeIndex) const {
	Math::Vector3d direction = getVertexPosition(edgeIndex) - getVertexPosition(edgeIndex + 1);
	direction.normalize();
	return direction;
}
Exemple #8
0
inline const QVector3D & Terrain::getVertexPosition( const QPoint & p ) const
{
	return getVertexPosition( p.x(), p.y() );
}
void main(void) {
	//transform data to simulate camera perspective and position
	vec3 vertex = getVertexPosition();
	vec3 normal = getNormal();
	vec3 backNormal = normal * -1.0;

	int state = int(floor(aState[0] + 0.5));
	int restyle = int(floor(aState[1] + 0.5));
	//HIDDEN state or first stage of xray rendering and no style state
	if (state == 254 || (uRenderingMode == 1 && !(state == 253 || state == 252)) || (uRenderingMode == 2 && (state == 253 || state == 252)))
	{
		vDiscard = 1.0;
		return;
	}
	else
	{
		vDiscard = 0.0;
	}
	
	if (uColorCoding){
		vec4 idColor = getIdColor();
		vFrontColor = idColor;
		vBackColor = idColor;
	}
	else{
		//ulightA[3] represents intensity of the light
		float lightAIntensity = ulightA[3];
		vec3 lightADirection = normalize(ulightA.xyz - vertex);
		float lightBIntensity = ulightB[3];
		vec3 lightBDirection = normalize(ulightB.xyz - vertex);
		
		//Light weighting
		float lightWeightA = max(dot(normal, lightADirection ) * lightAIntensity, 0.0);
		float lightWeightB = max(dot(normal, lightBDirection ) * lightBIntensity, 0.0);
		float backLightWeightA = max(dot(backNormal, lightADirection) * lightAIntensity, 0.0);
		float backLightWeightB = max(dot(backNormal, lightBDirection) * lightBIntensity, 0.0);
		
		//minimal constant value is for ambient light
		float lightWeighting = lightWeightA + lightWeightB + 0.4;
		float backLightWeighting = backLightWeightA + backLightWeightB + 0.4;
		
		//get base color or set highlighted colour
		vec4 baseColor = state == 253 ? uHighlightColour : getColor();
		
		//offset semitransparent triangles
		if (baseColor.a < 0.98 && uRenderingMode == 0)
		{
			mat4 transpose = mat4(1);
			vec3 trans = -0.002 * uMeter * normalize(normal);
			transpose[3] = vec4(trans,1.0);
			vertex = vec3(transpose * vec4(vertex, 1.0));
		}
		
		//transform colour to simulate lighting
		//preserve original alpha channel
		vFrontColor = vec4(baseColor.rgb * lightWeighting, baseColor.a);
		vBackColor = vec4(baseColor.rgb * backLightWeighting, baseColor.a);
	}
	vPosition = vertex;
	gl_Position = uPMatrix * uMVMatrix * vec4(vertex, 1.0);
	
}			
peano::kernel::spacetreegrid::SingleLevelEnumerator::Vector peano::kernel::spacetreegrid::SingleLevelEnumerator::getCellCenter() const {
    return getVertexPosition() + _fineGridCellSize/2.0;
}
peano::kernel::spacetreegrid::SingleLevelEnumerator::Vector peano::kernel::spacetreegrid::SingleLevelEnumerator::getVertexPosition() const {
    return getVertexPosition(LocalVertexIntegerIndex(0));
}
Geometry::Triangle_f TriangleAccessor::getTriangle() const {
	return Geometry::Triangle_f(Geometry::Vec3f(getVertexPosition(0)),
								Geometry::Vec3f(getVertexPosition(1)),
								Geometry::Vec3f(getVertexPosition(2)));
}
Exemple #13
0
Terrain::Terrain( const QString & heightMapPath, const QVector3D & size, const QVector3D & offset, const int & smoothingPasses )
{
	QImage heightMap( heightMapPath );
	if( heightMap.isNull() )
	{
		qFatal( "\"%s\" not found!", heightMapPath.toLocal8Bit().constData() );
	}
	mMapSize = heightMap.size();
	mSize = size;
	mOffset = offset;
	mToMapFactor = QSizeF( (float)mMapSize.width()/(float)mSize.x(), (float)mMapSize.height()/(float)mSize.z() );

	mVertices.resize( mMapSize.width() * mMapSize.height() );

	// prepare positions
	QVector<QVector3D> rawPositions;
	for( int h=0; h<mMapSize.height(); h++ )
	{
		for( int w=0; w<mMapSize.width(); w++ )
		{
			rawPositions.push_back( offset + QVector3D(
				w*(mSize.x()/mMapSize.width()),
				(float)qRed( heightMap.pixel( w, h ) )*(mSize.y()/256.0),
				h*(mSize.z()/mMapSize.height())
			) );
		}
	}

	// smoothed positions
	for( int i=0; i<smoothingPasses; i++ )
		rawPositions = smoothedPositions( rawPositions, mMapSize );

	// copy smoothed positions to vertex array
	for( int i=0; i<mVertices.size(); i++ )
	{
		mVertices[i].position = rawPositions[i];
	}

	// normals
	for( int h=0; h<mMapSize.height()-1; h++ )
	{
		for( int w=0; w<mMapSize.width()-1; w++ )
		{
			vertex( w, h ).normal = QVector3D::normal(
				getVertexPosition( w,   h ),
				getVertexPosition( w,   h+1 ),
				getVertexPosition( w+1, h )
			);
		}
		vertex( mMapSize.width()-1, h ).normal = QVector3D(0,1,0);	// last vertex in row
	}
	for( int w=0; w<mMapSize.width(); w++ )
	{
		vertex( w, mMapSize.height()-1 ).normal = QVector3D(0,1,0);	// last row
	}

	// texture coordinates
	for( int h=0; h<mMapSize.height(); h++ )
	{
		for( int w=0; w<mMapSize.width(); w++ )
		{
			vertex( w, h ).texCoord = QVector2D( w, h );
		}
	}
	mVertexBuffer = QGLBuffer( QGLBuffer::VertexBuffer );
	mVertexBuffer.create();
	mVertexBuffer.bind();
	mVertexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
	mVertexBuffer.allocate( mVertices.data(), mVertices.size()*VertexP3fN3fT2f::size() );
	mVertexBuffer.release();

	// indices
	QVector<unsigned int> indices;
	for( int h=0; h<mMapSize.height()-1; ++h )
	{
		for( int w=0; w<mMapSize.width(); ++w )
		{
			indices.push_back( w + h*(unsigned int)mMapSize.width() );
			indices.push_back( w + (h+1)*(unsigned int)mMapSize.width() );
		}
	}
	mIndexBuffer = QGLBuffer( QGLBuffer::IndexBuffer );
	mIndexBuffer.create();
	mIndexBuffer.bind();
	mIndexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
	mIndexBuffer.allocate( indices.data(), indices.size()*sizeof(unsigned int) );
	mIndexBuffer.release();
}
void SurfaceMeshShape::computeVolumeIntegrals()
{
	// Considering a surface mesh with thickness, the goal is to compute the following properties:
	// 1) volume = integral(over volume) dx dy dz
	// 2) center = integral(over volume) (x y z)^T dx dy dz / volume
	// 3) the inertia matrix without the mass density:
	// I = (Ixx Ixy Ixz) = integral(over volume) (y^2+z^2    -xy      -xz  ) dx dy dz
	//     (Iyx Iyy Iyz)                         (  -yx    x^2+z^2    -yz  )
	//     (Izx Izy Izz)                         (  -zx      -zy    x^2+y^2)
	// Each term of the matrix I can be evaluated independently and each monome can also be evaluated
	// independently and summed up after: integral(V) y^2+z^2 dV = integral(V) y^2 dV + integral(V) z^2 dV
	//
	// Therefore, we simply need to compute 10 different volume integral:
	// {1, x, y, z, x^2, y^2, z^2, xy, yz, zx}
	//
	// Example for the monome 'xy':
	// = integral(over volume) x.y dx dy dz = integral(over volume) x.y dV
	// = integral(over area) x.y dS * thickness
	// = [sum(over all triangles) integral(over triangle) x.y dS] * thickness
	//
	// Change the integration variables from cartesian coordinates to a parametrization of the
	// triangle ABC = {P | P = A + a.u + b.v}
	//   with
	//  { u=AB       the 1st triangle edge supporting the parametrization
	//  { v=AC       the 2nd triangle edge supporting the parametrization
	//  { 0<=a<=1    the triangle 1st coordinate in the new coordinate system (parametrized)
	//  { 0<=b<=1-a  the triangle 2nd coordinate in the new coordinate system (parametrized)
	//  => dS = |dP/db x dP/da|.db.da = |vxu|.db.da = |uxv|.db.da
	//  => x  = Px
	//  => y  = Py
	//
	// integral(over volume) x.y dx dy dz =
	// [sum(over all triangles) integral(over triangle) x.y dS] * thickness =
	// [sum(over all triangles) integral(from 0 to 1) integral(from 0 to 1-a) Px.Py db.da |uxv|] * thickness
	//
	// From here, the various integral terms can be found related to A, u and v using any formal integration tool.

	// Order: 1, x, y, z, x^2, y^2, z^2, xy, yz, zx
	Eigen::VectorXd integral(10);
	integral.setZero();

	for (auto const& triangle : getTriangles())
	{
		if (!triangle.isValid)
		{
			continue;
		}

		auto A = getVertexPosition(triangle.verticesId[0]);
		auto B = getVertexPosition(triangle.verticesId[1]);
		auto C = getVertexPosition(triangle.verticesId[2]);

		// Triangle parametrization P(a, b) = A + u.a + v.b  with u=AB and v=AC
		const Vector3d u = B - A;
		const Vector3d v = C - A;
		const double area = u.cross(v).norm() / 2.0; // Triangle area

		integral[0] += area;
		integral[1] += (A[0] + (u[0] + v[0]) / 3.0) * area;
		integral[2] += (A[1] + (u[1] + v[1]) / 3.0) * area;
		integral[3] += (A[2] + (u[2] + v[2]) / 3.0) * area;
		integral[4] +=
			(A[0] * (A[0] + 2.0 * (u[0] + v[0]) / 3.0) + (u[0] * v[0] + v[0] * v[0] + u[0] * u[0]) / 6.0) * area;
		integral[5] +=
			(A[1] * (A[1] + 2.0 * (u[1] + v[1]) / 3.0) + (u[1] * v[1] + v[1] * v[1] + u[1] * u[1]) / 6.0) * area;
		integral[6] +=
			(A[2] * (A[2] + 2.0 * (u[2] + v[2]) / 3.0) + (u[2] * v[2] + v[2] * v[2] + u[2] * u[2]) / 6.0) * area;
		integral[7] += (A[0] * A[1] + (A[0] * (u[1] + v[1]) + A[1] * (u[0] + v[0])) / 3.0) * area;
		integral[7] += ((u[0] * u[1] + v[0] * v[1]) / 6.0 + (u[0] * v[1] + u[1] * v[0]) / 12.0) * area;
		integral[8] += (A[1] * A[2] + (A[1] * (u[2] + v[2]) + A[2] * (u[1] + v[1])) / 3.0) * area;
		integral[8] += ((u[1] * u[2] + v[1] * v[2]) / 6.0 + (u[1] * v[2] + u[2] * v[1]) / 12.0) * area;
		integral[9] += (A[2] * A[0] + (A[2] * (u[0] + v[0]) + A[0] * (u[2] + v[2])) / 3.0) * area;
		integral[9] += ((u[2] * u[0] + v[2] * v[0]) / 6.0 + (u[2] * v[0] + u[0] * v[2]) / 12.0) * area;
	}

	// integral[0] is the sum of all triangle's area
	double area = integral[0];

	// Center of mass
	m_center = integral.segment(1, 3);
	if (area > epsilon)
	{
		m_center /= area;
	}

	// second moment of volume relative to center
	Vector3d centerSquared = m_center.cwiseProduct(m_center);
	m_secondMomentOfVolume(0, 0) = integral[5] + integral[6] - area * (centerSquared.y() + centerSquared.z());
	m_secondMomentOfVolume(1, 1) = integral[4] + integral[6] - area * (centerSquared.z() + centerSquared.x());
	m_secondMomentOfVolume(2, 2) = integral[4] + integral[5] - area * (centerSquared.x() + centerSquared.y());
	m_secondMomentOfVolume(0, 1) = -(integral[7] - area * m_center.x() * m_center.y());
	m_secondMomentOfVolume(1, 0) = m_secondMomentOfVolume(0, 1);
	m_secondMomentOfVolume(1, 2) = -(integral[8] - area * m_center.y() * m_center.z());
	m_secondMomentOfVolume(2, 1) = m_secondMomentOfVolume(1, 2);
	m_secondMomentOfVolume(0, 2) = -(integral[9] - area * m_center.z() * m_center.x());
	m_secondMomentOfVolume(2, 0) = m_secondMomentOfVolume(0, 2);

	m_secondMomentOfVolume *=  m_thickness;
	m_volume = (area * m_thickness);
}