コード例 #1
0
ファイル: Curve.cpp プロジェクト: euler0/Helium
void Curve::Evaluate( GraphDirection direction )
{
    uint32_t controlCount = 0;
    V_Vector3 points;
    {
        OS_HierarchyNodeDumbPtr::Iterator childItr = GetChildren().Begin();
        OS_HierarchyNodeDumbPtr::Iterator childEnd = GetChildren().End();
        for ( ; childItr != childEnd; ++childItr )
        {
            CurveControlPoint* point = Reflect::SafeCast< CurveControlPoint >( *childItr );
            if ( point )
            {
                points.push_back( point->GetPosition() );
                ++controlCount;
            }
        }
    }

    if ( controlCount < 4  || m_Type == CurveType::Linear ) 
    {     
        m_Points = points;
    }
    else if ( m_Type == CurveType::BSpline )
    {
        CurveGenerator::ComputeCurve( points, m_Resolution, m_Closed, CurveGenerator::kBSpline, m_Points ); 
    }
    else if ( m_Type == CurveType::CatmullRom )
    {
        CurveGenerator::ComputeCurve( points, m_Resolution, m_Closed, CurveGenerator::kCatmullRom, m_Points ); 
    }
    else
    {
        //whoa, did we get a bum curve type?
        HELIUM_BREAK();
    }


    //
    // Update buffer
    //

    if ( controlCount > 0 ) 
    {
        controlCount++;
    }

    uint32_t pointCount = (uint32_t)m_Points.size();
    if ( pointCount > 0 ) 
    {
        pointCount++;
    }

    m_Vertices->SetElementCount( controlCount + pointCount );
    m_Vertices->Update();

    Base::Evaluate(direction);
}
コード例 #2
0
ファイル: CreateTool.cpp プロジェクト: Fantasticer/Helium
void CreateTool::GenerateInstanceOffsets( PlacementStyle style, float radius, float instanceRadius, V_Vector3& positions )
{
	switch ( style )
	{
	case PlacementStyles::Grid:
		{
			float radiusSquared = radius * radius;
			int numInstances = MAX( 2, (int) sqrt( radiusSquared / ( instanceRadius * instanceRadius ) ) );
			float delta = radius * 2.0f / numInstances;

			for ( float x = -radius; x <= radius; x += delta )
			{
				for ( float y = -radius; y <= radius; y += delta )
				{
					if ( x * x + y * y < radiusSquared )
					{
						Vector3 v = ( Editor::UpVector * x ) + ( Editor::OutVector * y );
						positions.push_back( v );
					}
				}
			}
			break;
		}

	case PlacementStyles::Radial:
	default:
		{
			float currentRadius = 0.0f;
			while ( currentRadius < radius )
			{
				float circumference = static_cast< float32_t >( HELIUM_TWOPI ) * currentRadius;
				int numInstances = MAX( 1, (int) ( circumference / ( 2.0f * instanceRadius ) ) );

				float deltaAngle = static_cast< float32_t >( HELIUM_TWOPI ) / numInstances;
				float currentAngle = static_cast< float32_t >( HELIUM_TWOPI ) * rand() / ( (float) RAND_MAX + 1.0f );

				for ( int i = 0; i < numInstances; ++i )
				{
					float x = currentRadius * cos( currentAngle );
					float y = currentRadius * sin( currentAngle );
					Vector3 v = ( Editor::UpVector * x ) + ( Editor::OutVector * y );
					positions.push_back( v );

					currentAngle += deltaAngle;
					while ( currentAngle > HELIUM_TWOPI )
					{
						currentAngle -= static_cast< float32_t >( HELIUM_TWOPI );
					}
				}

				currentRadius += instanceRadius + instanceRadius;
			}
			break;
		}
	}
}
コード例 #3
0
static void MakeClosed(V_Vector3& cvs)
{
    // synthisize a new knot from the last two and first two cvs
    cvs.insert(cvs.begin(), cvs[cvs.size()-1]);
    cvs.insert(cvs.begin(), cvs[cvs.size()-2]);

    // this is 2 and 3 since we inserted @ 0 above
    cvs.push_back(cvs[2]);
    cvs.push_back(cvs[3]);
}
コード例 #4
0
ファイル: CreateTool.cpp プロジェクト: Fantasticer/Helium
void CreateTool::SetupInstanceOffsets( float instanceRadius, V_Vector3& instanceOffsets )
{
	instanceOffsets.clear();
	instanceOffsets.reserve( 256 );

	float adjustedInstanceRadius = instanceRadius / s_PaintDensity;

	GenerateInstanceOffsets( s_PaintPlacementStyle, s_PaintRadius, adjustedInstanceRadius, instanceOffsets );
	SelectInstanceOffsets( s_PaintDistributionStyle, s_PaintRadius, instanceOffsets );
	JitterInstanceOffsets( instanceRadius, s_PaintJitter, instanceOffsets );
	RandomizeInstanceOffsets( instanceOffsets );
}
コード例 #5
0
bool Frustum::IntersectsBox(const AlignedBox& box, bool precise) const
{
    MATH_FUNCTION_TIMER();

    if ( fabs((box.maximum - box.minimum).Length()) < LinearIntersectionError )
    {
        return IntersectsPoint( box.Center() );
    }
    else
    {
        f32 m, n;
        Vector3 c = box.Center();
        Vector3 d = box.maximum - c;

        for (i32 i=0; i<6; i++)
        {
            const Plane& p = (*this)[i];

            m = (c.x * p.A()) + (c.y * p.B()) + (c.z * p.C()) + p.D();
            n = (d.x * abs(p.A())) + (d.y * abs(p.B())) + (d.z * abs(p.C()));

            if (m + n < 0)
            {
                return false;
            }
        }

        if ( precise )
        {
#pragma TODO("This precise test should be using separated axis testing instead of triangle decimation")
            V_Vector3 vertices;
            vertices.reserve(8);
            box.GetVertices(vertices);

            V_Vector3 triangleList;
            triangleList.reserve(36);
            AlignedBox::GetTriangulated(vertices, triangleList);

            for ( int i=0; i<36; i+=3 )
            {
                if ( IntersectsTriangle( triangleList[i], triangleList[i+1], triangleList[i+2] ) )
                {
                    return true;
                }
            }

            return false;
        }
    }

    return true;
}
コード例 #6
0
bool CurveGenerator::ComputeCurve( const V_Vector3& controlPoints, const uint32_t resolution, const bool closed, const Type type, V_Vector3& points )
{
    bool success = false;

    if (resolution == 0 || controlPoints.size()<4)
        return success;

    success = true;

    points.clear( );

    V_Vector3 tempControlPoints( controlPoints );

    if( closed )
    {
        MakeClosed( tempControlPoints );    
    }
    else
    {
        MakeContinuous( tempControlPoints );
    }

    switch( type )
    {
    case CurveGenerator::kLinear:
        {
            points = tempControlPoints;
            break;
        }

    case CurveGenerator::kBSpline:
        {
            ComputeBSpline( tempControlPoints, resolution, closed, points );
            break;
        }

    case CurveGenerator::kCatmullRom:
        {
            ComputeCatmullRom( tempControlPoints, resolution, closed, points );
            break;
        }

    default:
        {
            points = tempControlPoints;
            break;
        }
    }

    return success;
}
コード例 #7
0
ファイル: Curve.cpp プロジェクト: euler0/Helium
float32_t Curve::CalculateCurveLength() const
{
    const Matrix4& globalTransform = this->GetGlobalTransform();
    V_Vector3 points = m_Points;
    float32_t curveLength = 0.f;
    for ( uint32_t i = 1; i < points.size() ; ++i )
    {
        Vector3 endPoint = points[i];
        Vector3 startPoint = points[i-1];
        globalTransform.TransformVertex( endPoint );
        globalTransform.TransformVertex( startPoint );
        curveLength += (endPoint - startPoint).Length();
    }
    return curveLength;
}
コード例 #8
0
ファイル: CreateTool.cpp プロジェクト: Fantasticer/Helium
void CreateTool::JitterInstanceOffsets( float instanceRadius, float maxJitter, V_Vector3& offsets )
{
	V_Vector3 jitterVectors;
	jitterVectors.push_back( Editor::UpVector );
	jitterVectors.push_back( Editor::OutVector );

	V_Vector3::iterator itr = offsets.begin();
	V_Vector3::iterator end = offsets.end();
	for ( ; itr != end; ++itr )
	{
		V_Vector3::const_iterator jitterItr = jitterVectors.begin();
		V_Vector3::const_iterator jitterEnd = jitterVectors.end();
		for ( ; jitterItr != jitterEnd; ++jitterItr )
		{
			int searchTries = 10;
			while ( searchTries > 0 )
			{
				--searchTries;
				float jitter = ( rand() / ( (float) RAND_MAX + 1.0f ) ) * 2.0f - 1.0f;
				float randomNumber = rand() / ( (float) RAND_MAX + 1.0f );
				float testNumber = GetNormalProbabilityFromPercent( jitter );
				if ( randomNumber <= testNumber )
				{
					(*itr) += (*jitterItr) * jitter * maxJitter;
					searchTries = 0;
				}
			}
		}
	}
}
コード例 #9
0
ファイル: AlignedBox.cpp プロジェクト: justinliew/Math
void AlignedBox::Transform(const Matrix4& matrix)
{
    // get the currents sample bounds
    V_Vector3 vertices;
    GetVertices( vertices );

    // reseed this box
    Reset();

    // iterate and resample the bounds
    V_Vector3::iterator itr = vertices.begin();
    V_Vector3::iterator end = vertices.end();
    for ( ; itr != end; ++itr )
    {
        // transform the sample
        matrix.TransformVertex( *itr );

        // test the sample
        Test( *itr );
    }
}
コード例 #10
0
void AlignedBox::GetVertices(V_Vector3& vertices) const
{
    vertices.resize(8);
    vertices[0] = Vector3 (maximum.x, maximum.y, maximum.z);
    vertices[1] = Vector3 (maximum.x, minimum.y, maximum.z);
    vertices[2] = Vector3 (minimum.x, minimum.y, maximum.z);
    vertices[3] = Vector3 (minimum.x, maximum.y, maximum.z);
    vertices[4] = Vector3 (maximum.x, maximum.y, minimum.z);
    vertices[5] = Vector3 (maximum.x, minimum.y, minimum.z);
    vertices[6] = Vector3 (minimum.x, minimum.y, minimum.z);
    vertices[7] = Vector3 (minimum.x, maximum.y, minimum.z);
}
コード例 #11
0
void ComputeCatmullRom( V_Vector3& controlPoints, const uint32_t resolution, const bool closed, V_Vector3& points  )
{
    float32_t t = 0.0f;
    uint32_t start = 0;
    uint32_t end   = resolution;// + 1;//for Catmull Rom

    uint32_t countControlPoints = uint32_t( controlPoints.size( ) - 3 );

    float32_t step = 1.0f/static_cast<float32_t>( resolution );

    for( uint32_t i = 0; i < countControlPoints; ++i )
    {
        t = 0.0f;
        end = resolution; 

        //if( i != 0 ) //for Catmull Rom
        //  start = 1;

        if( i == countControlPoints - 1 )
        {
            if( closed )
                break;

            end++;
        }

        //only incur the cost of copying from the STL vector once
        const Vector3& cp0 = controlPoints[ i ];
        const Vector3& cp1 = controlPoints[ i + 1 ];
        const Vector3& cp2 = controlPoints[ i + 2 ];
        const Vector3& cp3 = controlPoints[ i + 3 ];

        for( uint32_t j = start; j < end; ++j )
        {
            points.push_back( ComputePoint( t, cp0, cp1, cp2, cp3, CurveGenerator::kCatmullRom ) );
            t += step;
        }
    }
}
コード例 #12
0
void ComputeBSpline( V_Vector3& controlPoints, const uint32_t resolution, const bool closed, V_Vector3& points  )
{
    float32_t t = 0.0f;
    uint32_t start = 0;
    uint32_t end   = resolution;

    uint32_t countControlPoints = (uint32_t)( controlPoints.size( ) - 3 );

    float32_t step = 1.0f/static_cast<float32_t>( resolution );

    for( uint32_t i = 0; i < countControlPoints; ++i )
    {
        t = 0.0f;
        end = resolution;

        //push end forward to get the last point
        if( i == countControlPoints - 1 )
        {
            if( closed )
                break;

            end++;
        }

        //only incur the cost of copying from the STL vector once
        const Vector3& cp0 = controlPoints[ i ];
        const Vector3& cp1 = controlPoints[ i + 1 ];
        const Vector3& cp2 = controlPoints[ i + 2 ];
        const Vector3& cp3 = controlPoints[ i + 3 ];

        for( uint32_t j = start; j < end; ++j )
        {
            points.push_back( ComputePoint( t, cp0, cp1, cp2, cp3, CurveGenerator::kBSpline ) );
            t += step;
        }
    }
}
コード例 #13
0
static void MakeContinuous(V_Vector3& cvs)
{
    // ensure continuity through to first and last cvs by creating new begin and end tagent cvs
    Vector3 ab = cvs[0] - cvs[1];
    cvs.insert(cvs.begin(), cvs[0] + ab);

    Vector3 cd = cvs[ cvs.size() - 1 ] - cvs[ cvs.size() - 2 ];
    cvs.push_back(cvs[ cvs.size() - 1 ] + cd);
}
コード例 #14
0
bool Frustum::Contains(const AlignedBox& box) const
{
    MATH_FUNCTION_TIMER();

    V_Vector3 verts;
    box.GetVertices(verts);

    for (size_t i=0; i<verts.size(); i++)
    {
        // for each plane
        for (i32 j=0; j<6; j++)
        {
            const Plane& p = (*this)[j];

            // we need this vert to be above each plane
            if ((verts[i].x * p.A()) + (verts[i].y * p.B()) + (verts[i].z * p.C()) + p.D() < 0)
            {
                return false;
            }
        }
    }

    return true;
}
コード例 #15
0
void OctreeVisualizer::incomingOctreeCallback()
{
  scan_utils::Octree<char> octree(0, 0, 0, 0, 0, 0, 1, 0);
  octree.setFromMsg(octree_message_);

  std::list<scan_utils::Triangle> triangles;
  octree.getAllTriangles(triangles);

  V_Vector3 vertices;
  V_Vector3 normals;

  vertices.resize( triangles.size() * 3 );
  normals.resize( triangles.size() );
  size_t vertexIndex = 0;
  size_t normalIndex = 0;
  std::list<scan_utils::Triangle>::iterator it = triangles.begin();
  std::list<scan_utils::Triangle>::iterator end = triangles.end();
  for ( ; it != end; it++ )
  {
    Ogre::Vector3& v1 = vertices[vertexIndex++];
    Ogre::Vector3& v2 = vertices[vertexIndex++];
    Ogre::Vector3& v3 = vertices[vertexIndex++];
    Ogre::Vector3& n = normals[normalIndex++];

    v1 = Ogre::Vector3( it->p1.x, it->p1.y, it->p1.z );
    v2 = Ogre::Vector3( it->p2.x, it->p2.y, it->p2.z );
    v3 = Ogre::Vector3( it->p3.x, it->p3.y, it->p3.z );
    robotToOgre(v1);
    robotToOgre(v2);
    robotToOgre(v3);

    n = ( v2 - v1 ).crossProduct( v3 - v1 );
    n.normalise();
  }

  triangles_mutex_.lock();

  vertices_.clear();
  normals_.clear();

  vertices.swap( vertices_ );
  normals.swap( normals_ );

  new_message_ = true;
  triangles_mutex_.unlock();
}
コード例 #16
0
void AlignedBox::GetTriangulated(const V_Vector3& vertices, V_Vector3& triangleList, bool clear)
{
    if (clear)
    {
        triangleList.clear();
    }

    //front 2103
    triangleList.push_back(vertices[2]);
    triangleList.push_back(vertices[1]);
    triangleList.push_back(vertices[0]);

    triangleList.push_back(vertices[0]);
    triangleList.push_back(vertices[3]);
    triangleList.push_back(vertices[2]);

    //right 1540
    triangleList.push_back(vertices[1]);
    triangleList.push_back(vertices[5]);
    triangleList.push_back(vertices[4]);

    triangleList.push_back(vertices[4]);
    triangleList.push_back(vertices[0]);
    triangleList.push_back(vertices[1]);

    //back 5674
    triangleList.push_back(vertices[5]);
    triangleList.push_back(vertices[6]);
    triangleList.push_back(vertices[7]);

    triangleList.push_back(vertices[7]);
    triangleList.push_back(vertices[4]);
    triangleList.push_back(vertices[5]);

    //left 6237
    triangleList.push_back(vertices[6]);
    triangleList.push_back(vertices[2]);
    triangleList.push_back(vertices[3]);

    triangleList.push_back(vertices[3]);
    triangleList.push_back(vertices[7]);
    triangleList.push_back(vertices[6]);

    //top 3047
    triangleList.push_back(vertices[3]);
    triangleList.push_back(vertices[0]);
    triangleList.push_back(vertices[4]);

    triangleList.push_back(vertices[4]);
    triangleList.push_back(vertices[7]);
    triangleList.push_back(vertices[3]);

    //bottom 6512
    triangleList.push_back(vertices[6]);
    triangleList.push_back(vertices[5]);
    triangleList.push_back(vertices[1]);

    triangleList.push_back(vertices[1]);
    triangleList.push_back(vertices[2]);
    triangleList.push_back(vertices[6]);
}
コード例 #17
0
ファイル: CreateTool.cpp プロジェクト: Fantasticer/Helium
void CreateTool::SelectInstanceOffsets( DistributionStyle style, float radius, V_Vector3& offsets )
{
	V_Vector3 selectedOffsets;
	selectedOffsets.reserve( offsets.size() );

	V_Vector3::iterator itr = offsets.begin();
	V_Vector3::iterator end = offsets.end();
	for ( ; itr != end; ++itr )
	{
		switch ( style )
		{
		case DistributionStyles::Uniform:
			{
				float randomNumber = rand() / ( (float) RAND_MAX + 1.0f );
				if ( randomNumber <= 0.5f )
				{
					selectedOffsets.push_back( *itr );
				}
				break;
			}

		case DistributionStyles::Linear:
			{
				float radiusPercent = (*itr).Length() / radius;
				float randomNumber = rand() / ( (float) RAND_MAX + 1.0f );
				float testNumber = 1.0f - radiusPercent;
				if ( randomNumber <= testNumber )
				{
					selectedOffsets.push_back( *itr );
				}
				break;
			}

		case DistributionStyles::Normal:
			{
				float radiusPercent = (*itr).Length() / radius;
				float randomNumber = rand() / ( (float) RAND_MAX + 1.0f );
				float testNumber = GetNormalProbabilityFromPercent( radiusPercent );
				if ( randomNumber <= testNumber )
				{
					selectedOffsets.push_back( *itr );
				}
				break;
			}

		case DistributionStyles::Constant:
		default:
			selectedOffsets.push_back( *itr );
			break;
		}
	}

	offsets.clear();
	offsets.reserve( selectedOffsets.size() );
	itr = selectedOffsets.begin();
	end = selectedOffsets.end();
	for ( ; itr != end; ++itr )
	{
		offsets.push_back( *itr );
	}
}
コード例 #18
0
void AlignedBox::GetWireframe(const V_Vector3& vertices, V_Vector3& lineList, bool clear)
{
    if (clear)
    {
        lineList.clear();
    }

    //front 2103
    lineList.push_back(vertices[2]);
    lineList.push_back(vertices[1]);

    lineList.push_back(vertices[1]);
    lineList.push_back(vertices[0]);

    lineList.push_back(vertices[0]);
    lineList.push_back(vertices[3]);

    lineList.push_back(vertices[3]);
    lineList.push_back(vertices[2]);

    //back 5674
    lineList.push_back(vertices[5]);
    lineList.push_back(vertices[6]);

    lineList.push_back(vertices[6]);
    lineList.push_back(vertices[7]);

    lineList.push_back(vertices[7]);
    lineList.push_back(vertices[4]);

    lineList.push_back(vertices[4]);
    lineList.push_back(vertices[5]);

    //middle
    lineList.push_back(vertices[1]);
    lineList.push_back(vertices[5]);

    lineList.push_back(vertices[3]);
    lineList.push_back(vertices[7]);

    lineList.push_back(vertices[0]);
    lineList.push_back(vertices[4]);

    lineList.push_back(vertices[6]);
    lineList.push_back(vertices[2]);
}
コード例 #19
0
ファイル: CreateTool.cpp プロジェクト: Fantasticer/Helium
void CreateTool::RandomizeInstanceOffsets( V_Vector3& offsets )
{
	V_Vector3 newOffsets;
	newOffsets.reserve( offsets.size() );

	while ( offsets.size() )
	{
		V_Vector3::iterator itr = offsets.begin() + ( rand() % offsets.size() );
		newOffsets.push_back( *itr );
		offsets.erase( itr );
	}

	V_Vector3::iterator itr = newOffsets.begin();
	V_Vector3::iterator end = newOffsets.end();
	for ( ; itr != end; ++itr )
	{
		offsets.push_back( *itr );
	}
}