Example #1
0
Box3<Real> Wml::ContOrientedBox (int iQuantity, const Vector3<Real>* akPoint)
{
    Box3<Real> kBox;

    GaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(),
        kBox.Extents());

    // Let C be the box center and let U0, U1, and U2 be the box axes.  Each
    // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
    // following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
    // and max(y2).  The box center is then adjusted to be
    //   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
    //        0.5*(min(y2)+max(y2))*U2

    Vector3<Real> kDiff = akPoint[0] - kBox.Center();
    Real fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min;
    Real fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min;
    Real fY2Min = kDiff.Dot(kBox.Axis(2)), fY2Max = fY2Min;

    for (int i = 1; i < iQuantity; i++)
    {
        kDiff = akPoint[i] - kBox.Center();

        Real fY0 = kDiff.Dot(kBox.Axis(0));
        if ( fY0 < fY0Min )
            fY0Min = fY0;
        else if ( fY0 > fY0Max )
            fY0Max = fY0;

        Real fY1 = kDiff.Dot(kBox.Axis(1));
        if ( fY1 < fY1Min )
            fY1Min = fY1;
        else if ( fY1 > fY1Max )
            fY1Max = fY1;

        Real fY2 = kDiff.Dot(kBox.Axis(2));
        if ( fY2 < fY2Min )
            fY2Min = fY2;
        else if ( fY2 > fY2Max )
            fY2Max = fY2;
    }

    kBox.Center() += (((Real)0.5)*(fY0Min+fY0Max))*kBox.Axis(0) +
        (((Real)0.5)*(fY1Min+fY1Max))*kBox.Axis(1) +
        (((Real)0.5)*(fY2Min+fY2Max))*kBox.Axis(2);

    kBox.Extent(0) = ((Real)0.5)*(fY0Max - fY0Min);
    kBox.Extent(1) = ((Real)0.5)*(fY1Max - fY1Min);
    kBox.Extent(2) = ((Real)0.5)*(fY2Max - fY2Min);

    return kBox;
}
//----------------------------------------------------------------------------
bool Mgc::TestIntersection (const Line3& rkLine, const Box3& rkBox)
{
    Real fAWdU[3], fAWxDdU[3], fRhs;

    Vector3 kDiff = rkLine.Origin() - rkBox.Center();
    Vector3 kWxD = rkLine.Direction().Cross(kDiff);

    fAWdU[1] = Math::FAbs(rkLine.Direction().Dot(rkBox.Axis(1)));
    fAWdU[2] = Math::FAbs(rkLine.Direction().Dot(rkBox.Axis(2)));
    fAWxDdU[0] = Math::FAbs(kWxD.Dot(rkBox.Axis(0)));
    fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
    if ( fAWxDdU[0] > fRhs )
        return false;

    fAWdU[0] = Math::FAbs(rkLine.Direction().Dot(rkBox.Axis(0)));
    fAWxDdU[1] = Math::FAbs(kWxD.Dot(rkBox.Axis(1)));
    fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
    if ( fAWxDdU[1] > fRhs )
        return false;

    fAWxDdU[2] = Math::FAbs(kWxD.Dot(rkBox.Axis(2)));
    fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
    if ( fAWxDdU[2] > fRhs )
        return false;

    return true;
}
Example #3
0
void EditFaceDataMod::GetSubObjectTMs (SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) {
	if (!mc->localData) return;
	if (selLevel == SEL_OBJECT) return;	// shouldn't happen.
	EditFaceDataModData *modData = (EditFaceDataModData *) mc->localData;

	Mesh *mesh = modData->GetCacheMesh();
	MNMesh *mnmesh = modData->GetCacheMNMesh();
	if (!mesh && !mnmesh) return;

	Matrix3 tm = node->GetObjectTM(t);
	Box3 box;
	if (mesh) {
		BitArray sel = mesh->VertexTempSel ();
		if (!sel.NumberSet()) return;
		for (int i=0; i<mesh->numVerts; i++) if (sel[i]) box += mesh->verts[i] * tm;
	} else {
		int numSel, which;
		float value;
		bool valueDetermined;
		modData->DescribeSelection (numSel, which, value, valueDetermined);
		if (!numSel) return;
		if (numSel==1) {
			for (int j=0; j<mnmesh->f[which].deg; j++) box += mnmesh->P(mnmesh->f[which].vtx[j]) * tm;
		} else {
			for (int i=0; i<mnmesh->numf; i++) {
				if (mnmesh->f[i].GetFlag (MN_DEAD)) continue;
				if (!modData->GetFaceSel()[i]) continue;
				for (int j=0; j<mnmesh->f[i].deg; j++) box += mnmesh->P(mnmesh->f[i].vtx[j]) * tm;
			}
		}
	}
	Matrix3 ctm(1);
	ctm.SetTrans (box.Center());
	cb->TM (ctm,0);
}
Example #4
0
void    plRTProjDirLight::GetLocalBoundBox( TimeValue t, INode *node, ViewExp *vpt, Box3 &box )
{
    Point3  loc = node->GetObjectTM( t ).GetTrans();
    float   scaleFactor = vpt->NonScalingObjectSize() * vpt->GetVPWorldWidth( loc ) / 360.0f;
    float   width, height, depth;

    box = fMesh.getBoundingBox();
    // Because we want to scale about the origin, not the box center, we have to do this funky offset
    Point3  boxCenter = box.Center();
    box.Translate( -boxCenter );
    box.Scale( scaleFactor );
    boxCenter *= scaleFactor;
    box.Translate( boxCenter );

    if( ( extDispFlags & EXT_DISP_ONLY_SELECTED ) )
    {
        fProjPB->GetValue( kWidth, t, width, FOREVER );
        fProjPB->GetValue( kHeight, t, height, FOREVER );
        fProjPB->GetValue( kRange, t, depth, FOREVER );
        width /= 2.f;
        height /= 2.f;

        box += Point3( -width, -height, 0.f );
        box += Point3( width, height, -depth );
    }
}
void bhkProxyObject::BuildColBox()
{
	Box3 box; box.Init();
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);	
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Box3 box2; box2.Init();
				Mesh& mesh = tri->GetMesh();
				CalcAxisAlignedBox(mesh, box2, &wm);
				box += box2;
			}
		}
	}
	BuildBox(proxyMesh, box.Max().y-box.Min().y, box.Max().x-box.Min().x, box.Max().z-box.Min().z);

	MNMesh mn(proxyMesh);
	Matrix3 tm(true);
	tm.SetTranslate(box.Center());
	mn.Transform(tm);
	mn.OutToTri(proxyMesh);

	//proxyPos = box.Center();
	proxyPos = Point3::Origin;
	forceRedraw = true;
}
Example #6
0
void    plRTSpotLight::GetLocalBoundBox( TimeValue t, INode *node, ViewExp *vpt, Box3 &box )
{
    Point3  loc = node->GetObjectTM( t ).GetTrans();
    float   scaleFactor = vpt->NonScalingObjectSize() * vpt->GetVPWorldWidth( loc ) / 360.0f;
    float   width, depth;

    box = fMesh.getBoundingBox();
    // Because we want to scale about the origin, not the box center, we have to do this funky offset
    Point3  boxCenter = box.Center();
    box.Translate( -boxCenter );
    box.Scale( scaleFactor );
    boxCenter *= scaleFactor;
    box.Translate( boxCenter );

    // Include points for the spotlight. That means either the attenuated cone or 
    // our unattenuated cone display
    if( ( extDispFlags & EXT_DISP_ONLY_SELECTED ) )
    {
        if( GetUseAtten() ) 
            depth = GetAtten( t, ATTEN_END );
        else
            depth = 100.f + 50.f;   // Include arrows

        width = depth * tan( DegToRad( GetFallsize( t ) / 2.f ) );

        box += Point3( -width, -width, 0.f );
        box += Point3( width, width, -depth );
    }
}
Example #7
0
static inline void normalizeBox3(const Box3& target, const Box3& env, Box3& output)
{
    auto scale = env.Diagonal();
    auto center = env.Center();
    
    output.Set((target.Min()-center)/scale*2.0, 
        (target.Max()-center)/scale*2.0);
}
//----------------------------------------------------------------------------
bool Mgc::FindIntersection (const Segment3& rkSegment, const Box3& rkBox,
    int& riQuantity, Vector3 akPoint[2])
{
    // convert segment to box coordinates
    Vector3 kDiff = rkSegment.Origin() - rkBox.Center();
    Vector3 kOrigin(
        kDiff.Dot(rkBox.Axis(0)),
        kDiff.Dot(rkBox.Axis(1)),
        kDiff.Dot(rkBox.Axis(2))
    );
    Vector3 kDirection(
        rkSegment.Direction().Dot(rkBox.Axis(0)),
        rkSegment.Direction().Dot(rkBox.Axis(1)),
        rkSegment.Direction().Dot(rkBox.Axis(2))
    );

    Real fT0 = 0.0f, fT1 = 1.0f;
    bool bIntersects = FindIntersection(kOrigin,kDirection,rkBox.Extents(),
        fT0,fT1);

    if ( bIntersects )
    {
        if ( fT0 > 0.0f )
        {
            if ( fT1 < 1.0f )
            {
                riQuantity = 2;
                akPoint[0] = rkSegment.Origin() + fT0*rkSegment.Direction();
                akPoint[1] = rkSegment.Origin() + fT1*rkSegment.Direction();
            }
            else
            {
                riQuantity = 1;
                akPoint[0] = rkSegment.Origin() + fT0*rkSegment.Direction();
            }
        }
        else  // fT0 == 0
        {
            if ( fT1 < 1.0f )
            {
                riQuantity = 1;
                akPoint[0] = rkSegment.Origin() + fT1*rkSegment.Direction();
            }
            else  // fT1 == 1
            {
                // segment entirely in box
                riQuantity = 0;
            }
        }
    }
    else
    {
        riQuantity = 0;
    }

    return bIntersects;
}
void bhkRigidBodyModifier::BuildColBox(Mesh& mesh)
{
	Box3 box; box.Init();
	CalcAxisAlignedBox(mesh, box, NULL);
	BuildBox(mesh, box.Max().y-box.Min().y, box.Max().x-box.Min().x, box.Max().z-box.Min().z);

	MNMesh mn(mesh);
	Matrix3 tm(true);
	tm.Translate(box.Center());
	mn.Transform(tm);
	mn.OutToTri(mesh);
}
Example #10
0
bool Wml::InBox (const Vector3<Real>& rkPoint, const Box3<Real>& rkBox,
    Real fEpsilon)
{
    Vector3<Real> kDiff = rkPoint - rkBox.Center();
    for (int i = 0; i < 3; i++)
    {
        Real fCoeff = kDiff.Dot(rkBox.Axis(i));
        if ( Math<Real>::FAbs(fCoeff) > rkBox.Extent(i) + fEpsilon )
            return false;
    }
    return true;
}
Example #11
0
void Wml::BoxProjection (const Vector3<Real>& rkAxis,
    const Box3<Real>& rkBox, Real& rfMin, Real& rfMax)
{
    Real fOrigin = rkAxis.Dot(rkBox.Center());
    Real fMaximumExtent =
        Math<Real>::FAbs(rkBox.Extent(0)*rkAxis.Dot(rkBox.Axis(0))) +
        Math<Real>::FAbs(rkBox.Extent(1)*rkAxis.Dot(rkBox.Axis(1))) +
        Math<Real>::FAbs(rkBox.Extent(2)*rkAxis.Dot(rkBox.Axis(2)));

    rfMin = fOrigin - fMaximumExtent;
    rfMax = fOrigin + fMaximumExtent;
}
Example #12
0
bool Wml::Culled (const Plane3<Real>& rkPlane, const Box3<Real>& rkBox)
{
    Real fTmp[3] =
    {
        rkBox.Extent(0)*(rkPlane.GetNormal().Dot(rkBox.Axis(0))),
        rkBox.Extent(1)*(rkPlane.GetNormal().Dot(rkBox.Axis(1))),
        rkBox.Extent(2)*(rkPlane.GetNormal().Dot(rkBox.Axis(2)))
    };

    Real fRadius = Math<Real>::FAbs(fTmp[0]) + Math<Real>::FAbs(fTmp[1]) +
        Math<Real>::FAbs(fTmp[2]);

    Real fPseudoDistance = rkPlane.DistanceTo(rkBox.Center());
    return fPseudoDistance <= -fRadius;
}
//----------------------------------------------------------------------------
bool Mgc::TestIntersection (const Ray3& rkRay, const Box3& rkBox)
{
    Real fWdU[3], fAWdU[3], fDdU[3], fADdU[3], fAWxDdU[3], fRhs;

    Vector3 kDiff = rkRay.Origin() - rkBox.Center();

    fWdU[0] = rkRay.Direction().Dot(rkBox.Axis(0));
    fAWdU[0] = Math::FAbs(fWdU[0]);
    fDdU[0] = kDiff.Dot(rkBox.Axis(0));
    fADdU[0] = Math::FAbs(fDdU[0]);
    if ( fADdU[0] > rkBox.Extent(0) && fDdU[0]*fWdU[0] >= 0.0f )
        return false;

    fWdU[1] = rkRay.Direction().Dot(rkBox.Axis(1));
    fAWdU[1] = Math::FAbs(fWdU[1]);
    fDdU[1] = kDiff.Dot(rkBox.Axis(1));
    fADdU[1] = Math::FAbs(fDdU[1]);
    if ( fADdU[1] > rkBox.Extent(1) && fDdU[1]*fWdU[1] >= 0.0f )
        return false;

    fWdU[2] = rkRay.Direction().Dot(rkBox.Axis(2));
    fAWdU[2] = Math::FAbs(fWdU[2]);
    fDdU[2] = kDiff.Dot(rkBox.Axis(2));
    fADdU[2] = Math::FAbs(fDdU[2]);
    if ( fADdU[2] > rkBox.Extent(2) && fDdU[2]*fWdU[2] >= 0.0f )
        return false;

    Vector3 kWxD = rkRay.Direction().Cross(kDiff);

    fAWxDdU[0] = Math::FAbs(kWxD.Dot(rkBox.Axis(0)));
    fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
    if ( fAWxDdU[0] > fRhs )
        return false;

    fAWxDdU[1] = Math::FAbs(kWxD.Dot(rkBox.Axis(1)));
    fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
    if ( fAWxDdU[1] > fRhs )
        return false;

    fAWxDdU[2] = Math::FAbs(kWxD.Dot(rkBox.Axis(2)));
    fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
    if ( fAWxDdU[2] > fRhs )
        return false;

    return true;
}
//----------------------------------------------------------------------------
bool Mgc::TestIntersection (const Segment3& rkSegment, const Box3& rkBox)
{
    Real fAWdU[3], fADdU[3], fAWxDdU[3], fRhs;
    Vector3 kSDir = 0.5f*rkSegment.Direction();
    Vector3 kSCen = rkSegment.Origin() + kSDir;

    Vector3 kDiff = kSCen - rkBox.Center();

    fAWdU[0] = Math::FAbs(kSDir.Dot(rkBox.Axis(0)));
    fADdU[0] = Math::FAbs(kDiff.Dot(rkBox.Axis(0)));
    fRhs = rkBox.Extent(0) + fAWdU[0];
    if ( fADdU[0] > fRhs )
        return false;

    fAWdU[1] = Math::FAbs(kSDir.Dot(rkBox.Axis(1)));
    fADdU[1] = Math::FAbs(kDiff.Dot(rkBox.Axis(1)));
    fRhs = rkBox.Extent(1) + fAWdU[1];
    if ( fADdU[1] > fRhs )
        return false;

    fAWdU[2] = Math::FAbs(kSDir.Dot(rkBox.Axis(2)));
    fADdU[2] = Math::FAbs(kDiff.Dot(rkBox.Axis(2)));
    fRhs = rkBox.Extent(2) + fAWdU[2];
    if ( fADdU[2] > fRhs )
        return false;

    Vector3 kWxD = kSDir.Cross(kDiff);

    fAWxDdU[0] = Math::FAbs(kWxD.Dot(rkBox.Axis(0)));
    fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
    if ( fAWxDdU[0] > fRhs )
        return false;

    fAWxDdU[1] = Math::FAbs(kWxD.Dot(rkBox.Axis(1)));
    fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
    if ( fAWxDdU[1] > fRhs )
        return false;

    fAWxDdU[2] = Math::FAbs(kWxD.Dot(rkBox.Axis(2)));
    fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
    if ( fAWxDdU[2] > fRhs )
        return false;

    return true;
}
void MeshTopoData::PlanarMapNoScale(Point3 gNormal, UnwrapMod *mod )
{


	Matrix3 gtm;
	mod->UnwrapMatrixFromNormal(gNormal,gtm);

	gtm = Inverse(gtm);

	BitArray tempVSel;
	DetachFromGeoFaces(mFSel, tempVSel, mod);

	TimeValue t = GetCOREInterface()->GetTime();

	Box3 bounds;
	bounds.Init();
	for (int i = 0; i < TVMaps.v.Count(); i++)
	{
		if (tempVSel[i])
		{
			bounds += TVMaps.v[i].GetP();
		}
	}
	Point3 gCenter = bounds.Center();

	for (int i = 0; i < TVMaps.v.Count(); i++)
	{
		if (tempVSel[i])
		{
			TVMaps.v[i].SetFlag(0);
			TVMaps.v[i].SetInfluence(0.0f);

			Point3 tp = TVMaps.v[i].GetP() - gCenter;
			tp = tp * gtm;
			tp.z = 0.0f;

			SetTVVert(t,i,tp,mod);				
		}
	}
	mVSel = tempVSel;



}
Example #16
0
//----------------------------------------------------------------------------
static void MinimalBoxForAngles (int iQuantity, const Vector3* akPoint,
    Real afAngle[3], Box3& rkBox)
{
    Real fCos0 = Math::Cos(afAngle[0]);
    Real fSin0 = Math::Sin(afAngle[0]);
    Real fCos1 = Math::Cos(afAngle[1]);
    Real fSin1 = Math::Sin(afAngle[1]);
    Vector3 kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3 kRot;
    kRot.FromAxisAngle(kAxis,afAngle[2]);

    Vector3 kMin = akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        Vector3 kTest = akPoint[i]*kRot;

        if ( kTest.x < kMin.x )
            kMin.x = kTest.x;
        else if ( kTest.x > kMax.x )
            kMax.x = kTest.x;

        if ( kTest.y < kMin.y )
            kMin.y = kTest.y;
        else if ( kTest.y > kMax.y )
            kMax.y = kTest.y;

        if ( kTest.z < kMin.z )
            kMin.z = kTest.z;
        else if ( kTest.z > kMax.z )
            kMax.z = kTest.z;
    }

    Vector3 kMid = 0.5f*(kMax + kMin);
    Vector3 kRng = 0.5f*(kMax - kMin);

    rkBox.Center() = kRot*kMid;
    rkBox.Axis(0) = kRot.GetColumn(0);
    rkBox.Axis(1) = kRot.GetColumn(1);
    rkBox.Axis(2) = kRot.GetColumn(2);
    rkBox.Extent(0) = kRng.x;
    rkBox.Extent(1) = kRng.y;
    rkBox.Extent(2) = kRng.z;
}
Example #17
0
void MinBox3<Real>::MinimalBoxForAngles (int iQuantity,
    const Vector3<Real>* akPoint, Real afAngle[3], Box3<Real>& rkBox)
{
    Real fCos0 = Math<Real>::Cos(afAngle[0]);
    Real fSin0 = Math<Real>::Sin(afAngle[0]);
    Real fCos1 = Math<Real>::Cos(afAngle[1]);
    Real fSin1 = Math<Real>::Sin(afAngle[1]);
    Vector3<Real> kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3<Real> kRot(kAxis,afAngle[2]);

    Vector3<Real> kMin = akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        Vector3<Real> kTest = akPoint[i]*kRot;

        if ( kTest.X() < kMin.X() )
            kMin.X() = kTest.X();
        else if ( kTest.X() > kMax.X() )
            kMax.X() = kTest.X();

        if ( kTest.Y() < kMin.Y() )
            kMin.Y() = kTest.Y();
        else if ( kTest.Y() > kMax.Y() )
            kMax.Y() = kTest.Y();

        if ( kTest.Z() < kMin.Z() )
            kMin.Z() = kTest.Z();
        else if ( kTest.Z() > kMax.Z() )
            kMax.Z() = kTest.Z();
    }

    Vector3<Real> kMid = ((Real)0.5)*(kMax + kMin);
    Vector3<Real> kRng = ((Real)0.5)*(kMax - kMin);

    rkBox.Center() = kRot*kMid;
    rkBox.Axis(0) = kRot.GetColumn(0);
    rkBox.Axis(1) = kRot.GetColumn(1);
    rkBox.Axis(2) = kRot.GetColumn(2);
    rkBox.Extent(0) = kRng.X();
    rkBox.Extent(1) = kRng.Y();
    rkBox.Extent(2) = kRng.Z();
}
//----------------------------------------------------------------------------
bool Mgc::FindIntersection (const Line3& rkLine, const Box3& rkBox,
    int& riQuantity, Vector3 akPoint[2])
{
    // convert line to box coordinates
    Vector3 kDiff = rkLine.Origin() - rkBox.Center();
    Vector3 kOrigin(
        kDiff.Dot(rkBox.Axis(0)),
        kDiff.Dot(rkBox.Axis(1)),
        kDiff.Dot(rkBox.Axis(2))
    );
    Vector3 kDirection(
        rkLine.Direction().Dot(rkBox.Axis(0)),
        rkLine.Direction().Dot(rkBox.Axis(1)),
        rkLine.Direction().Dot(rkBox.Axis(2))
    );

    Real fT0 = -Math::MAX_REAL, fT1 = Math::MAX_REAL;
    bool bIntersects = FindIntersection(kOrigin,kDirection,rkBox.Extents(),
        fT0,fT1);

    if ( bIntersects )
    {
        if ( fT0 != fT1 )
        {
            riQuantity = 2;
            akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
            akPoint[1] = rkLine.Origin() + fT1*rkLine.Direction();
        }
        else
        {
            riQuantity = 1;
            akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
        }
    }
    else
    {
        riQuantity = 0;
    }

    return bIntersects;
}
Example #19
0
Vector3<Real> Wml::GetPoint (int iIndex, const Box3<Real>& rkBox)
{
    Vector3<Real> kPoint = rkBox.Center();

    if ( iIndex & 4 )
        kPoint += rkBox.Extent(2)*rkBox.Axis(2);
    else
        kPoint -= rkBox.Extent(2)*rkBox.Axis(2);

    if ( iIndex & 2 )
        kPoint += rkBox.Extent(1)*rkBox.Axis(1);
    else
        kPoint -= rkBox.Extent(1)*rkBox.Axis(1);

    if ( iIndex & 1 )
        kPoint += rkBox.Extent(0)*rkBox.Axis(0);
    else
        kPoint -= rkBox.Extent(0)*rkBox.Axis(0);

    return kPoint;
}
Example #20
0
void    plRTDirLight::GetLocalBoundBox( TimeValue t, INode *node, ViewExp *vpt, Box3 &box )
{
    Point3  loc = node->GetObjectTM( t ).GetTrans();
    float   scaleFactor = vpt->NonScalingObjectSize() * vpt->GetVPWorldWidth( loc ) / 360.0f;
    float   width, height, depth;

    box = fMesh.getBoundingBox();
    // Because we want to scale about the origin, not the box center, we have to do this funky offset
    Point3  boxCenter = box.Center();
    box.Translate( -boxCenter );
    box.Scale( scaleFactor );
    boxCenter *= scaleFactor;
    box.Translate( boxCenter );

    if( ( extDispFlags & EXT_DISP_ONLY_SELECTED ) )
    {
        width = 2 * 20.f + ( 10.f / 2.f );  // Add in half arrow size
        height = 2 * 20.f + ( 10.f / 2.f );
        depth = 100.f;

        box += Point3( -width, -height, 0.f );
        box += Point3( width, height, -depth );
    }
}
void 
UniformGrid::Display(GraphicsWindow *gw)
{
	return;
	Matrix3 tm(1);
//	gw->setTransform(tm);
	DrawBounds(gw, bounds);

	float sx,sy,sz;
	float incx,incy,incz;

	sx = 0.0f;
	sy = bounds.pmin.y;
	sz = bounds.pmin.z;
	incx = 0.0f;
	incy = (bounds.pmax.y - bounds.pmin.y)/width;
	incz = (bounds.pmax.z - bounds.pmin.z)/width;


	int index =0;
	float x,y,z;

	sx = bounds.pmin.x;
	sy = 0.0f;
	sz = bounds.pmin.z;
	incx = (bounds.pmax.x - bounds.pmin.x)/width;
	incy = 0.0f;
	incz = (bounds.pmax.z - bounds.pmin.z)/width;


	index =0;
	z = sz;
	for (int i = 0; i < width; i++)
	{
		x = sx;
		y = 0.0;
		for (int j = 0; j < width; j++)
		{
			Box3 b;
			b.Init();
			Point3 p(x,y,z);
			b += p;
			p.x += incx;
			p.y += incy;
			p.z += incz; 
			b += p;

			if (yGrid[index]!=NULL)
				{
				if (index == whichLargestCell)
					{
					Point3 color (1.0f,0.0f,0.0f);
					gw->setColor(LINE_COLOR,color);
					}
				else
					{
					Point3 color (0.0f,1.0f,0.0f);
					gw->setColor(LINE_COLOR,color);
					}

				gw->marker(&b.Center(),CIRCLE_MRKR);
				DrawBounds(gw, b);
				}
			
			index++;
			x += incx;
		}
		z += incz;
	}

	gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
	gw->marker(&debugP,BIG_BOX_MRKR);


	Point3 red (1.0f,0.0f,0.0f);

	gw->setColor(LINE_COLOR,red);
	gw->marker(&bounds.pmin,BIG_BOX_MRKR);
	Box3 cb;
	cb.Init();
	cb += bounds.pmin;
	cb.EnlargeBy(mRadius);
	DrawBounds(gw, cb);

}
Example #22
0
void
UniformGrid::Display(GraphicsWindow *gw)
{
	return;
	Matrix3 tm(1);
	gw->setTransform(tm);
	DrawBounds(gw, bounds);

	float sx,sy,sz;
	float incx,incy,incz;

	sx = 0.0f;
	sy = bounds.pmin.y;
	sz = bounds.pmin.z;
	incx = 0.0f;
	incy = (bounds.pmax.y - bounds.pmin.y)/width;
	incz = (bounds.pmax.z - bounds.pmin.z)/width;


	int index =0;
	float x,y,z;
	z = sz;
	for (int i = 0; i < width; i++)
	{
		x = 0.0;
		y = sy;
		for (int j = 0; j < width; j++)
		{
			Box3 b;
			b.Init();
			Point3 p(x,y,z);
			b += p;
			p.x += incx;
			p.y += incy;
			p.z += incz; 
			b += p;

			if (xGrid[index]->hit)
				{
				DrawBounds(gw, b);
				gw->marker(&b.Center(),ASTERISK_MRKR);

				}
			else DrawBounds(gw, b);
			index++;
			y += incy;
		}
		z += incz;
	}

	sx = bounds.pmin.x;
	sy = 0.0f;
	sz = bounds.pmin.z;
	incx = (bounds.pmax.x - bounds.pmin.x)/width;
	incy = 0.0f;
	incz = (bounds.pmax.z - bounds.pmin.z)/width;

/*
	index =0;
	z = sz;
	for (i = 0; i < width; i++)
	{
		x = sx;
		y = 0.0;
		for (int j = 0; j < width; j++)
		{
			Box3 b;
			b.Init();
			Point3 p(x,y,z);
			b += p;
			p.x += incx;
			p.y += incy;
			p.z += incz; 
			b += p;

			if (yGrid[index]->hit)
				{
				DrawBounds(gw, b);
				gw->marker(&b.Center(),CIRCLE_MRKR);

				}
			else DrawBounds(gw, b);
			index++;
			x += incx;
		}
		z += incz;
	}
*/
	gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
	gw->marker(&debugP,BIG_BOX_MRKR);


	Point3 red (1.0f,0.0f,0.0f);

	gw->setColor(LINE_COLOR,red);
	gw->marker(&bounds.pmin,BIG_BOX_MRKR);
}
Example #23
0
void 
CppOut::OutputObject(INode *node,TCHAR *fname)
{
    ObjectState os = node->EvalWorldState(theCppOut.ip->GetTime());
    assert(os.obj->SuperClassID()==GEOMOBJECT_CLASS_ID);
    BOOL needDel;
    NullView nullView;
    Mesh *mesh = ((GeomObject*)os.obj)->GetRenderMesh(ip->GetTime(),
                                                      node,nullView,needDel);
    if (!mesh) return;

    FILE *file = fopen(fname,_T("wt"));

    float maxLen = 0.0f, len;
    int i;
    Matrix3 tm = node->GetObjTMAfterWSM(theCppOut.ip->GetTime());
    AffineParts parts;
    decomp_affine(tm, &parts);

    if (file) {
        Box3 bb = mesh->getBoundingBox() * tm;
        Point3 center = bb.Center();
        for (i=0; i<mesh->getNumVerts(); i++) {
            Point3 v = tm * mesh->verts[i] - center;
            len = Length(v);
            if (len > maxLen)
                maxLen = len;
        }
        fprintf(file, "    mesh.setNumVerts(%d);\n", mesh->getNumVerts());
        fprintf(file, "    mesh.setNumFaces(%d);\n", mesh->getNumFaces());
        for (i=0; i<mesh->getNumVerts(); i++) {
            Point3 v = (tm  * mesh->verts[i] - center) / maxLen;
            fprintf(file,"    mesh.setVert(%d, size * Point3(%f,%f,%f));\n",
                    i, v.x, v.y, v.z);
        }

        for (i=0; i<mesh->getNumFaces(); i++) {
            if (parts.f < 0.0f)
                fprintf(file,"    mesh.faces[%d].setVerts(%d,%d,%d);\n",
                        i, mesh->faces[i].v[1], mesh->faces[i].v[0],
                        mesh->faces[i].v[2]);
            else
                fprintf(file,"    mesh.faces[%d].setVerts(%d,%d,%d);\n",
                        i, mesh->faces[i].v[0], mesh->faces[i].v[1],
                        mesh->faces[i].v[2]);
            if (parts.f < 0.0f) 
                fprintf(file,"    mesh.faces[%d].setEdgeVisFlags(%d,%d,%d);\n",
                        i,
                        mesh->faces[i].getEdgeVis(0) ? 1 : 0,
                        mesh->faces[i].getEdgeVis(2) ? 1 : 0,
                        mesh->faces[i].getEdgeVis(1) ? 1 : 0);
            else
                fprintf(file,"    mesh.faces[%d].setEdgeVisFlags(%d,%d,%d);\n",
                        i,
                        mesh->faces[i].getEdgeVis(0) ? 1 : 0,
                        mesh->faces[i].getEdgeVis(1) ? 1 : 0,
                        mesh->faces[i].getEdgeVis(2) ? 1 : 0);
            fprintf(file,"    mesh.faces[%d].setSmGroup(%x);\n",
                    i, mesh->faces[i].smGroup);
        }
		
        fclose(file);
    }	
    if (needDel) delete mesh;
}
Example #24
0
bool Wml::FindIntersection (const Box3<Real>& rkBox,
    const Vector3<Real>& rkBoxVelocity, const Sphere3<Real>& rkSphere,
    const Vector3<Real>& rkSphVelocity, Real& rfTFirst, Real fTMax,
    int& riQuantity, Vector3<Real>& rkP)
{
    // Find intersections relative to the coordinate system of the box.
    // The sphere is transformed to the box coordinates and the velocity of
    // the sphere is relative to the box.
    Vector3<Real> kCDiff = rkSphere.Center() - rkBox.Center();
    Vector3<Real> kVel = rkSphVelocity - rkBoxVelocity;
    Real fAx = kCDiff.Dot(rkBox.Axis(0));
    Real fAy = kCDiff.Dot(rkBox.Axis(1));
    Real fAz = kCDiff.Dot(rkBox.Axis(2));
    Real fVx = kVel.Dot(rkBox.Axis(0));
    Real fVy = kVel.Dot(rkBox.Axis(1));
    Real fVz = kVel.Dot(rkBox.Axis(2));

    // flip coordinate frame into the first octant
    int iSignX = 1;
    if ( fAx < (Real)0.0 )
    {
        fAx = -fAx;
        fVx = -fVx;
        iSignX = -1;
    }

    int iSignY = 1;
    if ( fAy < (Real)0.0 )
    {
        fAy = -fAy;
        fVy = -fVy;
        iSignY = -1;
    }

    int iSignZ = 1;
    if ( fAz < (Real)0.0 )
    {
        fAz = -fAz;
        fVz = -fVz;
        iSignZ = -1;
    }

    // intersection coordinates
    Real fIx, fIy, fIz;
    int iRetVal;

    if ( fAx <= rkBox.Extent(0) )
    {
        if ( fAy <= rkBox.Extent(1) )
        {
            if ( fAz <= rkBox.Extent(2) )
            {
                // sphere center inside box
                rfTFirst = (Real)0.0;
                riQuantity = 0;
                return false;
            }
            else
            {
                // sphere above face on axis Z
                iRetVal = FindFaceRegionIntersection(rkBox.Extent(0), 
                    rkBox.Extent(1),rkBox.Extent(2),fAx,fAy,fAz,fVx,fVy,fVz,
                    rfTFirst,rkSphere.Radius(),fIx,fIy,fIz,true);     
            }
        }
        else
        {
            if ( fAz <= rkBox.Extent(2) )
            {
                // sphere above face on axis Y
                iRetVal = FindFaceRegionIntersection(rkBox.Extent(0), 
                    rkBox.Extent(2),rkBox.Extent(1),fAx,fAz,fAy,fVx,fVz,fVy,
                    rfTFirst,rkSphere.Radius(),fIx,fIz,fIy,true);   
            }
            else
            {
                // sphere is above the edge formed by faces y and z
                iRetVal = FindEdgeRegionIntersection(rkBox.Extent(1), 
                    rkBox.Extent(0),rkBox.Extent(2),fAy,fAx,fAz,fVy,fVx,fVz,
                    rfTFirst,rkSphere.Radius(),fIy,fIx,fIz,true);
            }
        }
    }
    else
    {
        if ( fAy <= rkBox.Extent(1) )
        {
            if ( fAz <= rkBox.Extent(2) )
            {
                // sphere above face on axis X
                iRetVal = FindFaceRegionIntersection(rkBox.Extent(1),
                    rkBox.Extent(2),rkBox.Extent(0),fAy,fAz,fAx,fVy,fVz,fVx,
                    rfTFirst,rkSphere.Radius(),fIy,fIz,fIx,true);
            }
            else
            {
                // sphere is above the edge formed by faces x and z
                iRetVal = FindEdgeRegionIntersection(rkBox.Extent(0), 
                    rkBox.Extent(1),rkBox.Extent(2),fAx,fAy,fAz,fVx,fVy,fVz,
                    rfTFirst,rkSphere.Radius(),fIx,fIy,fIz,true);
            }
        }
        else
        {
            if ( fAz <= rkBox.Extent(2) )
            {
                // sphere is above the edge formed by faces x and y
                iRetVal = FindEdgeRegionIntersection(rkBox.Extent(0), 
                    rkBox.Extent(2),rkBox.Extent(1),fAx,fAz,fAy,fVx,fVz,fVy,
                    rfTFirst,rkSphere.Radius(),fIx,fIz,fIy,true);
            }
            else
            {
                // sphere is above the corner formed by faces x,y,z
                iRetVal = FindVertexRegionIntersection(rkBox.Extent(0),
                    rkBox.Extent(1),rkBox.Extent(2),fAx,fAy,fAz,fVx,fVy,fVz,
                    rfTFirst,rkSphere.Radius(),fIx,fIy,fIz);
            }
        }
    }

    if ( iRetVal != 1 || rfTFirst > fTMax )
    {
        riQuantity = 0;
        return false;
    }

    // calculate actual intersection (move point back into world coordinates)
    riQuantity = 1;
    rkP = rkBox.Center() + (iSignX*fIx)*rkBox.Axis(0) +
        (iSignY*fIy)*rkBox.Axis(1) + (iSignZ*fIz)*rkBox.Axis(2);
    return true;
}
Example #25
0
bool Wml::ContOrientedBox (int iQuantity, const Vector3<Real>* akPoint,
    const bool* abValid, Box3<Real>& rkBox)
{
    if ( !GaussPointsFit(iQuantity,akPoint,abValid,rkBox.Center(),
         rkBox.Axes(),rkBox.Extents()) )
    {
        return false;
    }

    // Let C be the box center and let U0, U1, and U2 be the box axes.  Each
    // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
    // following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
    // and max(y2).  The box center is then adjusted to be
    //   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
    //        0.5*(min(y2)+max(y2))*U2

    // get first valid vertex
    Vector3<Real> kDiff;
    Real fY0Min = (Real)0.0, fY0Max = (Real)0.0;
    Real fY1Min = (Real)0.0, fY1Max = (Real)0.0;
    Real fY2Min = (Real)0.0, fY2Max = (Real)0.0;
    int i;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            kDiff = akPoint[i] - rkBox.Center();
            fY0Min = kDiff.Dot(rkBox.Axis(0));
            fY0Max = fY0Min;
            fY1Min = kDiff.Dot(rkBox.Axis(1));
            fY1Max = fY1Min;
            fY2Min = kDiff.Dot(rkBox.Axis(2));
            fY2Max = fY2Min;
            break;
        }
    }

    for (i++; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            kDiff = akPoint[i] - rkBox.Center();

            Real fY0 = kDiff.Dot(rkBox.Axis(0));
            if ( fY0 < fY0Min )
                fY0Min = fY0;
            else if ( fY0 > fY0Max )
                fY0Max = fY0;

            Real fY1 = kDiff.Dot(rkBox.Axis(1));
            if ( fY1 < fY1Min )
                fY1Min = fY1;
            else if ( fY1 > fY1Max )
                fY1Max = fY1;

            Real fY2 = kDiff.Dot(rkBox.Axis(2));
            if ( fY2 < fY2Min )
                fY2Min = fY2;
            else if ( fY2 > fY2Max )
                fY2Max = fY2;
        }
    }

    rkBox.Center() += (0.5f*(fY0Min+fY0Max))*rkBox.Axis(0)
        + (0.5f*(fY1Min+fY1Max))*rkBox.Axis(1) +
        (0.5f*(fY2Min+fY2Max))*rkBox.Axis(2);

    rkBox.Extent(0) = 0.5f*(fY0Max - fY0Min);
    rkBox.Extent(1) = 0.5f*(fY1Max - fY1Min);
    rkBox.Extent(2) = 0.5f*(fY2Max - fY2Min);

    return true;
}
Example #26
0
void UnwrapMod::fnGizmoReset()
{


	
	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box

	for(int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];

		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm;//gverts.d[index].p;
				}
			}
		}	

	}
	
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
 	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	float scl = scale.x;
	if (scale.y > scl) scl = scale.y;
	if (scale.z > scl) scl = scale.z;
	scale.x = scl;
	scale.y = scl;
	scale.z = scl;
	
	tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
	tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
	tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP))
		tm.SetRow(3,center);
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		center.z = bounds.pmin.z;
		tm.SetRow(3,center);
	}
		

	Matrix3 ptm(1), id(1);
	tm = tm ;
	SetXFormPacket tmpck(tm,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();


	theHold.Accept(GetString(IDS_MAPPING_RESET));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
Example #27
0
Box3<Real> Wml::MergeBoxes (const Box3<Real>& rkBox0,
    const Box3<Real>& rkBox1)
{
    // construct a box that contains the input boxes
    Box3<Real> kBox;

    // The first guess at the box center.  This value will be updated later
    // after the input box vertices are projected onto axes determined by an
    // average of box axes.
    kBox.Center() = ((Real)0.5)*(rkBox0.Center() + rkBox1.Center());

    // A box's axes, when viewed as the columns of a matrix, form a rotation
    // matrix.  The input box axes are converted to quaternions.  The average
    // quaternion is computed, then normalized to unit length.  The result is
    // the slerp of the two input quaternions with t-value of 1/2.  The result
    // is converted back to a rotation matrix and its columns are selected as
    // the merged box axes.
    Quaternion<Real> kQ0, kQ1;
    kQ0.FromRotationMatrix(rkBox0.Axes());
    kQ1.FromRotationMatrix(rkBox1.Axes());
    if ( kQ0.Dot(kQ1) < 0.0f )
        kQ1 = -kQ1;

    Quaternion<Real> kQ = kQ0 + kQ1;
    Real fInvLength = Math<Real>::InvSqrt(kQ.Dot(kQ));
    kQ = fInvLength*kQ;
    kQ.ToRotationMatrix(kBox.Axes());

    // Project the input box vertices onto the merged-box axes.  Each axis
    // D[i] containing the current center C has a minimum projected value
    // pmin[i] and a maximum projected value pmax[i].  The corresponding end
    // points on the axes are C+pmin[i]*D[i] and C+pmax[i]*D[i].  The point C
    // is not necessarily the midpoint for any of the intervals.  The actual
    // box center will be adjusted from C to a point C' that is the midpoint
    // of each interval,
    //   C' = C + sum_{i=0}^2 0.5*(pmin[i]+pmax[i])*D[i]
    // The box extents are
    //   e[i] = 0.5*(pmax[i]-pmin[i])

    int i, j;
    Real fDot;
    Vector3<Real> akVertex[8], kDiff;
    Vector3<Real> kMin = Vector3<Real>::ZERO;
    Vector3<Real> kMax = Vector3<Real>::ZERO;

    rkBox0.ComputeVertices(akVertex);
    for (i = 0; i < 8; i++)
    {
        kDiff = akVertex[i] - kBox.Center();
        for (j = 0; j < 3; j++)
        {
            fDot = kDiff.Dot(kBox.Axis(j));
            if ( fDot > kMax[j] )
                kMax[j] = fDot;
            else if ( fDot < kMin[j] )
                kMin[j] = fDot;
        }
    }

    rkBox1.ComputeVertices(akVertex);
    for (i = 0; i < 8; i++)
    {
        kDiff = akVertex[i] - kBox.Center();
        for (j = 0; j < 3; j++)
        {
            fDot = kDiff.Dot(kBox.Axis(j));
            if ( fDot > kMax[j] )
                kMax[j] = fDot;
            else if ( fDot < kMin[j] )
                kMin[j] = fDot;
        }
    }

    // [kMin,kMax] is the axis-aligned box in the coordinate system of the
    // merged box axes.  Update the current box center to be the center of
    // the new box.  Compute the extens based on the new center.
    for (j = 0; j < 3; j++)
    {
        kBox.Center() += (((Real)0.5)*(kMax[j]+kMin[j]))*kBox.Axis(j);
        kBox.Extent(j) = ((Real)0.5)*(kMax[j]-kMin[j]);
    }

    return kBox;
}
Example #28
0
void UnwrapMod::fnAlignAndFit(int axis)
{



	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	TimeValue t = GetCOREInterface()->GetTime();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) *tm;//gverts.d[index].p;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
				}
				pnorm += VectorTransform(Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]),tm);
				ct++;
			}
		}	
	}

	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();

	pnorm = pnorm / (float) ct;
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	
 	if (axis == 0) // x axi
	{

  		tm.SetRow(0,Point3(0.0f,-scale.y,0.0f));
		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(scale.x,0.0f,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)  || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.x = bounds.pmin.x;
			tm.SetRow(3,center);
		}		

		Matrix3 ptm(1), id(1);
		tm = tm ;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 1) // y axi
	{
  		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
 		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(0.0f,scale.y,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.y = bounds.pmin.y;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 2) //z axi
	{
		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
		tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
		tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.z = bounds.pmin.z;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 3) // normal
	{
		int numberOfSelectionGroups = 0;
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			if (ld->GetFaceSelection().NumberSet())
				numberOfSelectionGroups++;
		}
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (numberOfSelectionGroups > 1))
		{
			//get our tm
			Matrix3 tm;
			UnwrapMatrixFromNormal(pnorm,tm);
 			Matrix3 itm = Inverse(tm);
			//find our x and y scale
			float xmax = 0.0f;
			float ymax = 0.0f;
			float zmax = 0.0f;
			Box3 localBounds;
			localBounds.Init();
			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{
				MeshTopoData *ld = mMeshTopoData[ldID];
				Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
				for (int k = 0; k < ld->GetNumberFaces(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}
			}

//			center = localBounds.Center();
			xmax = localBounds.pmax.x - localBounds.pmin.x;
			ymax = localBounds.pmax.y - localBounds.pmin.y;
			zmax = localBounds.pmax.z - localBounds.pmin.z;

			if (xmax < 0.001f)
				xmax = 1.0f;
			if (ymax < 0.001f)
				ymax = 1.0f;
			if (zmax < 0.001f)
				zmax = 1.0f;

			Point3 vec;
			vec = Normalize(tm.GetRow(0)) * xmax;
			tm.SetRow(0,vec);

			vec = Normalize(tm.GetRow(1)) * ymax;
			tm.SetRow(1,vec);

			vec = Normalize(tm.GetRow(2)) * zmax;
			tm.SetRow(2,vec);


			tm.SetRow(3,center);
			

			Matrix3 ptm(1), id(1);
			tm = tm ;
			SetXFormPacket tmpck(tm,ptm);
			tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
		}		
		else if ((fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP)|| (fnGetMapMode() == BOXMAP))
		{

			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{


				//get our first 2 rings
				Tab<int> openEdges;
				Tab<int> startRing;
				Tab<int> endRing;

				MeshTopoData *ld =  mMeshTopoData[ldID];

				//skip any local data that has no selections
				if (ld->GetFaceSelection().NumberSet() == 0)
					continue;

				Matrix3 nodeTM = mMeshTopoData.GetNodeTM(t,ldID);

				for (int i = 0; i < ld->GetNumberGeomEdges(); i++)//TVMaps.gePtrList.Count(); i++)
				{
					int numberSelectedFaces = 0;
					int ct = ld->GetGeomEdgeNumberOfConnectedFaces(i);//TVMaps.gePtrList[i]->faceList.Count();
					for (int j = 0; j < ct; j++)
					{
						int faceIndex = ld->GetGeomEdgeConnectedFace(i,j);//TVMaps.gePtrList[i]->faceList[j];
						if (ld->GetFaceSelected(faceIndex))//fsel[faceIndex])
							numberSelectedFaces++;
					}
					if (numberSelectedFaces == 1)
					{
						openEdges.Append(1,&i,1000);
						
					}
				}

				GetOpenEdges(ld,openEdges, startRing);
				GetOpenEdges(ld,openEdges, endRing);
				Point3 zVec = pnorm;

				Point3 centerS(0.0f,0.0f,0.0f), centerE;
				if ((startRing.Count() != 0) && (endRing.Count() != 0))
				{
					//get the center start
					Box3 BoundsS, BoundsE;
					BoundsS.Init();
					BoundsE.Init();

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}


					for (int i = 0; i < endRing.Count(); i++)
					{
						int eIndex = endRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsE += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsE += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					
					centerS = BoundsS.Center();
					centerE = BoundsE.Center();
					//create the vec
					zVec = centerE - centerS;

				}
				else if ((startRing.Count() != 0) && (endRing.Count() == 0))
				{
					//get the center start
					Box3 BoundsS;
					BoundsS.Init();
					

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a =  ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b =  ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					centerS = BoundsS.Center();
					

					int farthestPoint= -1;
					Point3 fp;
					float farthestDist= 0.0f;
					for (int k=0; k < ld->GetNumberFaces(); k++) 
					{
						if (ld->GetFaceSelected(k))
						{
								// Grap the three points, xformed
							int pcount = 3;
								//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
							pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

							
							for (int j=0; j<pcount; j++) 
							{
								int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
								
								Point3 p = ld->GetGeomVert(index)* nodeTM;//gverts.d[index].p;
								float d = LengthSquared(p-centerS);
								if ((d > farthestDist) || (farthestPoint == -1))
								{
									farthestDist = d;
									farthestPoint = index;
									fp = p;
								}							
							}
						}
					}

					
					
					centerE = fp;
					//create the vec
					zVec = centerE - centerS;

				}
				else
				{
					zVec = Point3(0.0f,0.0f,1.0f);
				}


				//get our tm
				Matrix3 tm;
				UnwrapMatrixFromNormal(zVec,tm);
				tm.SetRow(3,centerS);
 				Matrix3 itm = Inverse(tm);
				//find our x and y scale
				float xmax = 0.0f;
				float ymax = 0.0f;
				float zmax = 0.0f;
				Box3 localBounds;
				localBounds.Init();
				for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * nodeTM * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}

				center = localBounds.Center() * tm;

				if (fnGetMapMode() == CYLINDRICALMAP)
				{
					if ((startRing.Count() == 0) && (endRing.Count() == 0))
					{
						centerS = center;
						centerS.z = localBounds.pmin.z;					
					}
					else
					{

						centerS = centerS * itm;
						centerS.z = localBounds.pmin.z;
						centerS = centerS * tm;
					}
				}
				else if ((fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
				{
					centerS = center;
				}

				Point3 bc = localBounds.Center();
				bc.z = localBounds.pmin.z;
				bc = bc * tm;

				xmax = localBounds.pmax.x - localBounds.pmin.x;
				ymax = localBounds.pmax.y - localBounds.pmin.y;
				zmax = localBounds.pmax.z - localBounds.pmin.z;

				Point3 vec;
				vec = Normalize(tm.GetRow(0)) * xmax;
				tm.SetRow(0,vec);

				vec = Normalize(tm.GetRow(1)) * ymax;
				tm.SetRow(1,vec);

				vec = Normalize(tm.GetRow(2)) * zmax;
				tm.SetRow(2,vec);


				
				tm.SetRow(3,centerS);
				

				Matrix3 ptm(1), id(1);
				tm = tm;
				SetXFormPacket tmpck(tm,ptm);
				tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
			}
			
		}
	}
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_ALIGN));

	fnGetGizmoTM();

	if (ip) ip->RedrawViews(ip->GetTime());

}
Example #29
0
void UnwrapMod::fnGizmoCenter()
{
	//get our tm
	//set the tm scale



	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
				// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm; //gverts.d[index].p * tm;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index) * tm; //gverts.d[index].p;
				}
				pnorm += Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]);
				ct++;
			}
		}	
	}


	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	pnorm = pnorm / (float) ct;//gfaces.Count();
	

	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
	// build the scale



	//get our tm
	Matrix3 tm(1);
	tm = *fnGetGizmoTM();
	Matrix3 initialTM = tm;

	Point3 vec2;
	vec2 = Normalize(tm.GetRow(0)); 
	tm.SetRow(0,vec2);

	vec2 = Normalize(tm.GetRow(1)) ;
	tm.SetRow(1,vec2);

	vec2 = Normalize(tm.GetRow(2)); 
	tm.SetRow(2,vec2);

	tm.SetRow(3,center);


 	Matrix3 itm = Inverse(tm);
	//find our x and y scale
	Box3 localBounds;
	localBounds.Init();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{		// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * tm * itm;
					localBounds += p;

		//			if (fabs(p.x) > xmax) xmax = fabs(p.x);
		//			if (fabs(p.y) > ymax) ymax = fabs(p.y);
		//			if (fabs(p.z) > zmax) zmax = fabs(p.z);
				}
			}
		}
	}

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP))
		center = localBounds.Center() * tm;
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		Point3 zvec = initialTM.GetRow(2);
		
//		center = center * tm;

		center = localBounds.Center() * tm - (zvec * 0.5f);
		

	}


	initialTM.SetRow(3,center);


	Matrix3 ptm(1), id(1);
	initialTM = initialTM ;
	SetXFormPacket tmpck(initialTM,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);

	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_FIT));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
//----------------------------------------------------------------------------
Real Mgc::SqrDistance (const Line3& rkLine, const Box3& rkBox,
    Real* pfLParam, Real* pfBParam0, Real* pfBParam1, Real* pfBParam2)
{
#ifdef _DEBUG
    // The four parameters pointers are either all non-null or all null.
    if ( pfLParam )
    {
        assert( pfBParam0 && pfBParam1 && pfBParam2 );
    }
    else
    {
        assert( !pfBParam0 && !pfBParam1 && !pfBParam2 );
    }
#endif

    // compute coordinates of line in box coordinate system
    Vector3 kDiff = rkLine.Origin() - rkBox.Center();
    Vector3 kPnt(kDiff.Dot(rkBox.Axis(0)),kDiff.Dot(rkBox.Axis(1)),
        kDiff.Dot(rkBox.Axis(2)));
    Vector3 kDir(rkLine.Direction().Dot(rkBox.Axis(0)),
        rkLine.Direction().Dot(rkBox.Axis(1)),
        rkLine.Direction().Dot(rkBox.Axis(2)));

    // Apply reflections so that direction vector has nonnegative components.
    bool bReflect[3];
    int i;
    for (i = 0; i < 3; i++)
    {
        if ( kDir[i] < 0.0f )
        {
            kPnt[i] = -kPnt[i];
            kDir[i] = -kDir[i];
            bReflect[i] = true;
        }
        else
        {
            bReflect[i] = false;
        }
    }

    Real fSqrDistance = 0.0f;

    if ( kDir.x > 0.0f )
    {
        if ( kDir.y > 0.0f )
        {
            if ( kDir.z > 0.0f )
            {
                // (+,+,+)
                CaseNoZeros(kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
            else
            {
                // (+,+,0)
                Case0(0,1,2,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
        }
        else
        {
            if ( kDir.z > 0.0f )
            {
                // (+,0,+)
                Case0(0,2,1,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
            else
            {
                // (+,0,0)
                Case00(0,1,2,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
        }
    }
    else
    {
        if ( kDir.y > 0.0f )
        {
            if ( kDir.z > 0.0f )
            {
                // (0,+,+)
                Case0(1,2,0,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
            else
            {
                // (0,+,0)
                Case00(1,0,2,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
        }
        else
        {
            if ( kDir.z > 0.0f )
            {
                // (0,0,+)
                Case00(2,0,1,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
            }
            else
            {
                // (0,0,0)
                Case000(kPnt,rkBox,fSqrDistance);
                if ( pfLParam )
                    *pfLParam = 0.0f;
            }
        }
    }

    if ( pfLParam )
    {
        // undo reflections
        for (i = 0; i < 3; i++)
        {
            if ( bReflect[i] )
                kPnt[i] = -kPnt[i];
        }

        *pfBParam0 = kPnt.x;
        *pfBParam1 = kPnt.y;
        *pfBParam2 = kPnt.z;
    }

    return fSqrDistance;
}