Beispiel #1
0
BOOL Bounds::LineIntersection(const Vect &v1, const Vect &v2, float &fT) const
{
    float tMax = M_INFINITE;
    float tMin = -M_INFINITE;

    Vect rayVect = (v2-v1);
    float rayLength = rayVect.Len();
    Vect rayDir = rayVect*(1.0f/rayLength);

    Vect center = GetCenter();
    Vect E = Max-center;
    Vect T = center-v1;

    for(int i=0; i<3; i++)
    {
        float e = T.ptr[i];
        float f = rayDir.ptr[i];
        float fI = 1.0f/f;

        if(fabs(f) > 0.0f)
        {
            float t1 = (e+E.ptr[i])*fI;
            float t2 = (e-E.ptr[i])*fI;
            if(t1 > t2)
            {
                if(t2 > tMin) tMin = t2;
                if(t1 < tMax) tMax = t1;
            }
            else
            {
                if(t1 > tMin) tMin = t1;
                if(t2 < tMax) tMax = t2;
            }
            if(tMin > tMax) return FALSE;
            if(tMax < 0.0f) return FALSE;
        }
        else if( ((-e - E.ptr[i]) > 0.0f) ||
                 ((-e + E.ptr[i]) < 0.0f) )
        {
            return FALSE;
        }

        if(tMin > rayLength) return FALSE;
    }

    if(tMin > 0.0f)
    {
        fT = (tMin/rayLength);
        return TRUE;
    }
    else
    {
        fT = (tMax/rayLength);
        return TRUE; 
    }
}
Beispiel #2
0
BOOL PointOnFiniteLine(const Vect &lineV1, const Vect &lineV2, const Vect &p)
{
    Vect line = lineV2-lineV1;
    float lineDist = line.Len();

    Plane plane;
    plane.Dir  = line*(1.0f/lineDist);
    plane.Dist = plane.Dir.Dot(lineV1);

    float dist = p.DistFromPlane(plane);
    if((dist < 0.0f) || (dist > lineDist))
        return FALSE;

    float fT = (dist/lineDist);

    return p.CloseTo(Lerp(lineV1, lineV2, fT));
}
Beispiel #3
0
//vector version
void CalcTorque(Vect &val1, const Vect &val2, float torque, float minAdjust, float fT)
{
    if(val1 == val2)
        return;

    Vect line = (val2-val1);
    float origDist = line.Len();
    Vect dir = line * (1.0f/origDist);

    float torqueDist = origDist*torque;                 //uses distance to determine torque speed

    float adjustDist = torqueDist*fT;

    if(torqueDist < minAdjust) torqueDist = minAdjust;  //prevents torque from going too slow

    if(adjustDist <= (origDist-LARGE_EPSILON))
        val1 += dir*adjustDist;                         //adds toque to val1
    else
        val1 = val2;                                    //sets val1 to val2 if overshot with the minimum torque value
}
Beispiel #4
0
Vect CartToPolar(const Vect &cart)
{
    Vect polar;

    polar.z = cart.Len();

    if(CloseFloat(polar.z, 0.0f, EPSILON))
    {
        polar.x = 0.0f;
        polar.y = 0.0f;
        polar.z = 0.0f;
    }
    else
    {
        polar.x = asin(cart.y / polar.z);
        polar.y = atan2(cart.x, cart.z);
    }

    return polar;
}
Beispiel #5
0
BOOL Plane::GetDoublePlaneIntersection(const Plane &p2, Vect &intOrigin, Vect &intDir) const
{
    float fCosAngle = (Dir|p2.Dir);
    float fSinAngle = sqrt(1.0f-(fCosAngle*fCosAngle));

    if(fabs(fSinAngle) < LARGE_EPSILON)
        return FALSE;

    float fInvSinAngle = 1.0f/fSinAngle;

    float fChi1 = (Dist-(fCosAngle*p2.Dist))*fInvSinAngle;
    float fChi2 = (p2.Dist-(fCosAngle*Dist))*fInvSinAngle;

    intDir      = Dir^p2.Dir;
    float iLen  = 1.0f/intDir.Len();
    intDir     *= iLen;

    intOrigin   = (Dir*fChi1) + (p2.Dir*fChi2);
    intOrigin  *= iLen;

    return TRUE;
}
void RotationManipulator::ProcessMouseRay(const Vect &cameraDir, float scale, const Vect &rayOrig, const Vect &rayDir)
{
    traceIn(RotationManipulator::ProcessMouseRay);

    activeAxis = -1;
    curCameraDir = cameraDir;

    Matrix mat;
    mat.SetIdentity();
    mat.Translate(GetWorldPos());
    mat.Scale(scale, scale, scale);

    bManipulating = false;

    DWORD i,j;

    for(i=0; i<3; i++)
    {
        for(j=0; j<30; j++)
        {
            DWORD jp1 = (j == 29) ? 0 : j+1;

            Vect norm = axisNorms[i][j];

            if(norm.Dot(cameraDir) > 0.01f)
                continue;

            Vect  v1 = axisLines[i][j];
            Vect  v2 = axisLines[i][jp1];

            v1.TransformPoint(mat);
            v2.TransformPoint(mat);

            Vect  lineVec = (v2-v1);
            float lineLen = lineVec.Len();

            Vect  lineDir = lineVec*(1.0f/lineLen);

            float fT1, fT2;
            if(ClosestLinePoints(rayOrig, rayDir, v1, lineDir, fT1, fT2))
            {
                if((fT2 < 0.0f) || (fT2 > lineLen))
                    continue;

                Vect closestPoint1 = rayOrig+(rayDir*fT1);
                Vect closestPoint2 = v1+(lineDir*fT2);

                if(closestPoint1.Dist(closestPoint2) < (0.4f*scale))
                {
                    Vect axis(0.0f, 0.0f, 0.0f);
                    axis.ptr[i] = 1.0f;

                    activeAxis = i;
                    clickDir  = cameraDir.Cross(axis.Cross(norm)).Cross(cameraDir).Norm();
                    clickOrig = closestPoint1;

                    bManipulating = true;
                    return;
                }
            }
        }
    }

    mat.SetIdentity();
    mat.Translate(GetWorldPos());
    mat.Rotate(Quat().SetLookDirection(cameraDir));
    mat.Scale(scale*1.25f, scale*1.25f, scale*1.25f);

    for(j=0; j<30; j++)
    {
        DWORD jp1 = (j == 29) ? 0 : j+1;

        Vect norm = axisNorms[2][j];
        Vect v1   = axisLines[2][j];
        Vect v2   = axisLines[2][jp1];

        v1.TransformPoint(mat);
        v2.TransformPoint(mat);

        norm.TransformVector(mat);

        Vect  lineVec = (v2-v1);
        float lineLen = lineVec.Len();

        Vect  lineDir = lineVec*(1.0f/lineLen);

        float fT1, fT2;
        if(ClosestLinePoints(rayOrig, rayDir, v1, lineDir, fT1, fT2))
        {
            if((fT2 < 0.0f) || (fT2 > lineLen))
                continue;

            Vect closestPoint1 = rayOrig+(rayDir*fT1);
            Vect closestPoint2 = v1+(lineDir*fT2);

            if(closestPoint1.Dist(closestPoint2) < (0.6f*scale))
            {
                activeAxis = 4;
                clickDir  = cameraDir.Cross(norm);
                clickOrig = closestPoint1;

                curCameraDir = cameraDir;

                bManipulating = true;
                return;
            }
        }
    }

    traceOut;
}
Beispiel #7
0
void EditorMesh::BuildLightmapUVs(float maxAngle, float adjVal, int seperationUnits)
{
    Vect maxSize = bounds.Max-bounds.Min;

    //adjVal *= MAX(maxSize.x, MAX(maxSize.y, maxSize.z));
    adjVal *= bounds.GetDiamater();

    int i, j;

    MakePolyEdges();

    maxAngle = cosf(RAD(maxAngle));

    BitList ProcessedPolys, ProcessedEdges, ProcessedVerts;
    List<UINT> UnprocessedPolys;

    ProcessedPolys.SetSize(PolyList.Num());
    ProcessedEdges.SetSize(PolyEdgeList.Num());
    ProcessedVerts.SetSize(VertList.Num());

    UnprocessedPolys.SetSize(PolyList.Num());
    for(i=0; i<UnprocessedPolys.Num(); i++)
        UnprocessedPolys[i] = i;

    List<UVSection> Sections;
    BitList         SplitVerts;

    SplitVerts.SetSize(VertList.Num());

    //go through each polygon and find neighboring polygons
    while(UnprocessedPolys.Num())
    {
        UINT curPoly = UnprocessedPolys[0];

        List<UINT> SectionPolys;
        UVSection &section = *Sections.CreateNew();
        section.mapDir = GetPolyDir(curPoly);

        List<Vect> PolyLines;

        // calling this recursively will build us up a section based upon this poly
        AddLMPolyInfo info(curPoly, maxAngle, section.mapDir, SectionPolys, PolyLines, UnprocessedPolys, ProcessedPolys, ProcessedEdges);
        AddLightmapUVPoly(info);

        section.mapDir.Norm();

        //find best mapping direction
        Vect XDir, YDir;

        BitList addedLines;
        addedLines.SetSize(PolyLines.Num());

        float bestLength = 0.0f;
        Vect bestDir;

        for(i=0; i<PolyLines.Num(); i++)
        {
            if(addedLines[i]) continue;

            addedLines.Set(i);

            Vect &line1 = PolyLines[i];
            Vect line1Norm = (line1 + (section.mapDir * -section.mapDir.Dot(line1))).Norm();

            Vect lineTotal = line1;

            for(j=i+1; j<PolyLines.Num(); j++)
            {
                if(addedLines[j]) continue;

                Vect &line2 = PolyLines[j];
                Vect line2Norm = (line2 + (section.mapDir * -section.mapDir.Dot(line2))).Norm();

                if(line1Norm.Dot(line2Norm) > 0.9f) //about 10 degrees
                {
                    lineTotal += line2;
                    addedLines.Set(j);
                }
            }

            float length = lineTotal.Len();
            if(length > bestLength)
            {
                bestDir = lineTotal.Norm();
                bestLength = length;
            }
        }

        if(section.mapDir.CloseTo(bestDir) || (-section.mapDir).CloseTo(bestDir))
        {
            if(bestDir.x > bestDir.y)
            {
                if(bestDir.x > bestDir.z)
                    *(DWORD*)&bestDir.x |= 0x80000000;
                else
                    *(DWORD*)&bestDir.z |= 0x80000000;
            }
            else
            {
                if(bestDir.y > bestDir.z)
                    *(DWORD*)&bestDir.y |= 0x80000000;
                else
                    *(DWORD*)&bestDir.z |= 0x80000000;
            }
        }

        YDir = bestDir.Cross(section.mapDir).Norm();
        XDir = YDir.Cross(section.mapDir).Norm();

        /*if(section.mapDir.GetAbs().CloseTo(Vect(0.0f, 1.0f, 0.0f)))
        {
            float fOne = (*(DWORD*)&section.mapDir.y & 0x80000000) ? -1.0f : 1.0f;

            XDir.Set(fOne, 0.0f, 0.0f);
            YDir.Set(0.0f, 0.0f, fOne);
        }
        else
        {
            XDir = Vect(0.0f, 1.0f, 0.0f).Cross(section.mapDir).Norm();
            YDir = XDir.Cross(section.mapDir).Norm();
        }*/

        float top, bottom, left, right;

        //project UVs onto this section
        for(i=0; i<SectionPolys.Num(); i++)
        {
            PolyFace &poly = PolyList[SectionPolys[i]];
            for(j=0; j<poly.Faces.Num(); j++)
            {
                UINT faceID = poly.Faces[j];
                Face &f = FaceList[faceID];

                section.Faces << faceID;

                for(int k=0; k<3; k++)
                {
                    UINT vert = f.ptr[k];

                    Vect &v = VertList[vert];

                    Vect2 uv;
                    uv.x = XDir.Dot(v);
                    uv.y = YDir.Dot(v);

                    if(!section.ProjectedVerts.Num())
                    {
                        left = right = uv.x;
                        top = bottom = uv.y;
                    }
                    else
                    {
                        if(uv.x < left) left = uv.x;
                        else if(uv.x > right) right = uv.x;

                        if(uv.y < top) top = uv.y;
                        else if(uv.y > bottom) bottom = uv.y;
                    }

                    section.Verts << vert;
                    section.ProjectedVerts << uv;
                }
            }
        }

        section.width  = (right-left)+(adjVal*2.0f);
        section.height = (bottom-top)+(adjVal*2.0f);

        for(i=0; i<section.Verts.Num(); i++)
        {
            section.ProjectedVerts[i].x -= left-adjVal;
            section.ProjectedVerts[i].y -= top-adjVal;
        }

        //find any verts that might need splitting
        section.SplitVerts.SetSize(section.Verts.Num());

        for(i=0; i<section.Verts.Num(); i++)
        {
            BOOL bFoundVert = FALSE;
            UINT vert = section.Verts[i];

            if(SplitVerts[vert])
                bFoundVert = TRUE;
            else 
            {
                for(j=0; j<Sections.Num()-1; j++)
                {
                    UVSection &prevSection = Sections[j];

                    if(prevSection.Verts.HasValue(vert))
                    {
                        SplitVerts.Set(vert);
                        bFoundVert = TRUE;
                        break;
                    }
                }
            }

            if(bFoundVert)
                section.SplitVerts.Set(i);
        }
    }

    //split verts where the lightmap coordinates are
    for(i=1; i<Sections.Num(); i++)
    {
        UVSection &section = Sections[i];
        for(j=0; j<section.SplitVerts.Num(); j++)
        {
            if(section.SplitVerts[j])
            {
                UINT faceID  = j/3;
                UINT faceVert = j%3;
                UINT vertID = section.Verts[j];

                UINT newVertID = VertList.Num();
                Face &f = FaceList[faceID];

                f.ptr[faceVert] = newVertID;

                VertList.Add(VertList[vertID]);
                UVList.Add(UVList[vertID]);
                NormalList.Add(NormalList[vertID]);
                if(TangentList.Num())
                    TangentList.Add(TangentList[vertID]);
            }
        }
    }

    LMUVList.SetSize(VertList.Num());

    //find the most optimal way to put sections together
    BestStorageInfo info(Sections, seperationUnits);
    FindBestUVStorage(info);

    float curSizeI = 1.0f/MAX(info.curSize.x, info.curSize.y);

    for(i=0; i<info.CurStorage.Num(); i++)
    {
        StorageData &data = info.CurStorage[i];
        UVSection &section = Sections[data.item];
        for(j=0; j<section.Verts.Num(); j++)
        {
            UINT vertID = section.Verts[j];
            if(ProcessedVerts[vertID]) continue;

            Vect2 &v = section.ProjectedVerts[j];
            Vect2 newPos;

            if(data.bRot)
            {
                newPos.x = section.height-v.y;
                newPos.y = v.x;
            }
            else
                newPos = v;

            LMUVList[vertID] = (data.pos+newPos)*curSizeI;

            ProcessedVerts.Set(vertID);
        }
    }

    //free data
    for(i=0; i<Sections.Num(); i++)
        Sections[i].FreeData();
    Sections.Clear();

    FreePolyEdges();
}