예제 #1
0
파일: Line.cpp 프로젝트: daillen/Math
void Line::Transform(const Matrix4& m)
{
    HELIUM_MATH_FUNCTION_TIMER();

    m.TransformVertex(m_Origin);
    m.TransformVertex(m_Point);
}
예제 #2
0
void PrimitiveCircle::DrawHiddenBack(DrawArgs* args, const SceneGraph::Camera* camera, const Matrix4& m) const
{
#ifdef VIEWPORT_REFACTOR
    if (!SetState())
        return;

    int i = 0, count = 0;
    float stepAngle = (float32_t)HELIUM_TWOPI / (float32_t)(m_RadiusSteps);

    Vector3 position (m.t.x, m.t.y, m.t.z);

    Vector3 cameraVector;
    camera->GetPosition(cameraVector);
    cameraVector -= position;
    cameraVector.Normalize();

    for (int x=0; x<m_RadiusSteps; x++)
    {
        float theta = (float32_t)(x) * stepAngle;

        // circle point 1
        Vector3 v1 (0.0f, (float32_t)(cos(theta)) * m_Radius, (float32_t)(sin(theta)) * m_Radius);

        // circle point 2
        Vector3 v2 (0.0f, (float32_t)(cos(theta + stepAngle)) * m_Radius, (float32_t)(sin(theta + stepAngle)) * m_Radius);

        // middle point of circle segment
        Vector3 v = (v1 + v2) * 0.5f;

        // in global space
        m.TransformVertex(v);

        v -= position;
        v.Normalize();

        // if not pointing away from the camera vector, render
        if (v.Dot(cameraVector) > 1.0f - HELIUM_CRITICAL_DOT_PRODUCT)
        {
            m_Device->DrawPrimitive(D3DPT_LINELIST, (UINT)GetBaseIndex()+i, 1);
            count++;
        }

        // increment vertex offset
        i+=2;
    }

    args->m_LineCount += count;
#endif
}
예제 #3
0
void AlignedBox::Transform(const Matrix4& matrix)
{
    // get the currents sample bounds
    Math::V_Vector3 vertices;
    GetVertices( vertices );

    // reseed this box
    Reset();

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

        // test the sample
        Test( *itr );
    }
}
예제 #4
0
파일: Curve.cpp 프로젝트: euler0/Helium
UndoCommandPtr Curve::CenterTransform()
{
    BatchUndoCommandPtr batch = new BatchUndoCommand();

    batch->Push( Base::CenterTransform() );

    if ( GetNumberControlPoints() == 0 )
    {
        return batch;
    }


    //
    // We are going to move all control points, so just snap shot
    //

    batch->Push( SnapShot() );


    //
    // Compute the centered position
    //

    Vector3 position = Vector3::Zero;

    {
        uint32_t controlPointCount = 0;
        OS_HierarchyNodeDumbPtr::Iterator childItr = GetChildren().Begin();
        OS_HierarchyNodeDumbPtr::Iterator childEnd = GetChildren().End();
        for ( ; childItr != childEnd; ++childItr )
        {
            CurveControlPoint* point = Reflect::SafeCast< CurveControlPoint >( *childItr );
            if ( point )
            {
                ++controlPointCount;
                position += point->GetPosition();
            }
        }
        position /= (float32_t)controlPointCount;
    }

    m_GlobalTransform.TransformVertex( position );


    //
    // Offset the control points
    //

    Matrix4 m = m_GlobalTransform;

    m.t = position;

    m = m_GlobalTransform * m.Inverted();

    {
        OS_HierarchyNodeDumbPtr::Iterator childItr = GetChildren().Begin();
        OS_HierarchyNodeDumbPtr::Iterator childEnd = GetChildren().End();
        for ( ; childItr != childEnd; ++childItr )
        {
            CurveControlPoint* point = Reflect::SafeCast< CurveControlPoint >( *childItr );
            if ( point )
            {
                Vector3 p = point->GetPosition();

                m.TransformVertex( p );

                batch->Push( new PropertyUndoCommand< Vector3 >( new Helium::MemberProperty< CurveControlPoint, Vector3 >( point, &CurveControlPoint::GetPosition, &CurveControlPoint::SetPosition ), p ) );
            }
        }
    }


    //
    // Recompute global transform
    //

    // our new global transform is just translated to the new position
    m_GlobalTransform.t = position;

    // this will recompute the local components
    SetGlobalTransform( m_GlobalTransform );

    // update the transform object
    Evaluate( GraphDirections::Downstream );

    // update each child's local transform to stay in the same global position
    for ( OS_HierarchyNodeDumbPtr::Iterator itr = m_Children.Begin(), end = m_Children.End(); itr != end; ++itr )
    {
        HierarchyNode* n = *itr;

        Transform* t = Reflect::SafeCast<Transform>( n );

        if ( !t )
        {
            continue;
        }

        batch->Push( t->ComputeObjectComponents() );
    }

    Dirty();

    return batch;
}
예제 #5
0
AxesFlags PrimitiveAxes::PickAxis(const Matrix4& transform, Line pick, float32_t err)
{
    Vector3 offset;
    float32_t minX = m_Length, minY = m_Length, minZ = m_Length;

    Vector3 axisOrigin (Vector3::Zero);
    Vector3 axisEnd (m_Length, 0.f, 0.f);

    transform.TransformVertex (axisOrigin);
    transform.TransformVertex (axisEnd);

    if (pick.IntersectsSegment (axisOrigin, axisEnd, err, NULL, &offset))
    {
        float32_t dist = offset.Length();
        if (dist > 0.0f && dist < minX)
        {
            minX = dist;
        }
    }

    axisEnd = Vector3(0.f, m_Length, 0.f);
    transform.TransformVertex (axisEnd);

    if (pick.IntersectsSegment (axisOrigin, axisEnd, err, NULL, &offset))
    {
        float32_t dist = offset.Length();
        if (dist > 0.0f && dist < minY)
        {
            minY = dist;
        }
    }

    axisEnd = Vector3(0.f, 0.f, m_Length);
    transform.TransformVertex (axisEnd);

    if (pick.IntersectsSegment (axisOrigin, axisEnd, err, NULL, &offset))
    {
        float32_t dist = offset.Length();
        if (dist > 0.0f && dist < minZ)
        {
            minZ = dist;
        }
    }

    if ((minX == minY) && (minY == minZ))
    {
        return MultipleAxes::None;
    }

    if (minX <= minY && minX <= minZ)
    {
        return MultipleAxes::X;
    }

    if (minY <= minX && minY <= minZ)
    {
        return MultipleAxes::Y;
    }

    if (minZ <= minX && minZ <= minY)
        return MultipleAxes::Z;

    return MultipleAxes::None;
}