Esempio n. 1
0
void
APITestUtil::PointTests()
{
	// now let's build a test object
	NURBSSet nset;
	Matrix3 mat;
	mat.IdentityMatrix();


	// 6 types of points...

	// 1: build an independent point
	int indPnt = MakeTestPoint(nset);


	// 2: now a constrained point
	int ptPnt = MakeTestPointCPoint(nset, indPnt);



	// build a cv curve
	int cvCrv = MakeTestCVCurve(nset, mat);

	// 3: a constrained point on that curve
	int crvPnt = MakeTestCurveCPoint(nset, cvCrv);



	// build a cv surface
	int cvSurf = MakeTestCVSurface(nset, mat);

	// 4: a constrained point on that surface
	int srfPnt = MakeTestSurfCPoint(nset, cvSurf);

	// 5: Curve Curve intersection point
	int cvCrv1 = MakeTestCVCurve(nset, TransMatrix(Point3(65, 0, 0)) * RotateZMatrix(0.5));
	int intPoint = MakeTestCurveCurve(nset, cvCrv, cvCrv1, FALSE);

	// 6: Curve Surface intersection point.
	int cvCrv2 = MakeTestCVCurve(nset, RotateXMatrix(PI/2.0f) * TransMatrix(Point3(0, 0, -175)));
	int srfIntPoint = MakeTestCurveSurface(nset, cvSurf, cvCrv2);


	Object *obj = CreateNURBSObject(mpIp, &nset, mat);
	INode *node = mpIp->CreateObjectNode(obj);
	node->SetName(GetString(IDS_PNT_TEST_OBJECT));
	mpIp->RedrawViews(mpIp->GetTime());
}
Esempio n. 2
0
int
APITestUtil::MakeTestUVLoftSurface(NURBSSet &nset)
{
	Matrix3 scale = ScaleMatrix(Point3(50, 50, 50));
	Matrix3 rotate = RotateZMatrix(PI/2.0f);
	int cu0 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 0)));
	int cu1 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 20)));
	int cu2 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 40)));

	int cv0 = P2Curve(nset, TransMatrix(Point3(50, 50, 0)));
	int cv1 = P2Curve(nset, TransMatrix(Point3(-50, 50, 0)));
	int cv2 = P2Curve(nset, TransMatrix(Point3(-50, -50, 0)));
	int cv3 = P2Curve(nset, TransMatrix(Point3(50, -50, 0)));

	NURBSUVLoftSurface *s = new NURBSUVLoftSurface();
	s->SetName(GetString(IDS_UVLOFT_SURFACE));
	s->SetNSet(&nset);
	s->AppendUCurve(cu0);
	s->AppendUCurve(cu1);
	s->AppendUCurve(cu2);

	s->AppendVCurve(cv0);
	s->AppendVCurve(cv1);
	s->AppendVCurve(cv2);
	s->AppendVCurve(cv3);

	return nset.AppendObject(s);
}
Esempio n. 3
0
void
APITestUtil::COSTests()
{
	// now let's build a test object
	NURBSSet nset;
	Matrix3 mat;
	mat.IdentityMatrix();

	// build a cv surface
	int cvSurf = MakeTestCVSurface(nset, mat);

	// Now an Iso Curve on the CV surface
	int isoCrv1 = MakeTestIsoCurveU(nset, cvSurf);

	// Now an Iso Curve on the CV surface
	int isoCrv2 = MakeTestIsoCurveV(nset, cvSurf);

	// build a CV Curve on Surface
	int cvCOS = MakeTestCurveOnSurface(nset, cvSurf);

	// build a Point Curve on Surface
	int pntCOS = MakeTestPointCurveOnSurface(nset, cvSurf);

	// build a Surface Normal Offset Curve
	int cnoCrf = MakeTestSurfaceNormalCurve(nset, cvCOS);

	// build a surface surface intersection curve
	int cvSurf1 = MakeTestCVSurface(nset, TransMatrix(Point3(0.0, 0.0, -30.0)) * RotateYMatrix(0.5));
	int intCrv = MakeTestSurfSurfIntersectionCurve(nset, cvSurf, cvSurf1);

	// Vector Projection Curve
	int cvCrv1 = MakeTestCVCurve(nset, TransMatrix(Point3(-100, -200, 40)));
	int vecCrv = MakeTestProjectVectorCurve(nset, cvSurf, cvCrv1);

	// Normal Normal Curve
	int cvCrv2 = MakeTestCVCurve(nset, TransMatrix(Point3(0, -250, 10)));
	int nrmCrv = MakeTestProjectNormalCurve(nset, cvSurf1, cvCrv2);


	Object *obj = CreateNURBSObject(mpIp, &nset, mat);
	INode *node = mpIp->CreateObjectNode(obj);
	node->SetName(GetString(IDS_COS_TEST_OBJECT));
	mpIp->RedrawViews(mpIp->GetTime());
}
Esempio n. 4
0
int
APITestUtil::MakeTestLatheSurface(NURBSSet &nset)
{
	int p = MakeCurveToLathe(nset);

	NURBSLatheSurface *s = new NURBSLatheSurface();
	s->SetName(GetString(IDS_LATHE_SURFACE));
	s->SetNSet(&nset);

	s->SetParent(p);
	Matrix3 mat = TransMatrix(Point3(200, 200, 0));
	s->SetAxis(0, mat);

	s->FlipNormals(TRUE);

	return nset.AppendObject(s);
}
Esempio n. 5
0
//////////////////////////////////////////////////////////////////////////
// lookAt
void BcMat4d::lookAt( const BcVec3d& Position, const BcVec3d& LookAt, const BcVec3d& UpVec )
{
	const BcVec3d Front = ( Position - LookAt ).normal();
	const BcVec3d Side = Front.cross( UpVec ).normal();
	const BcVec3d Up = Side.cross( Front ).normal();

	BcMat4d RotMatrix( BcVec4d( Side.x(),		Up.x(),		-Front.x(),		0.0f ),
	                   BcVec4d( Side.y(),		Up.y(),		-Front.y(),		0.0f ),
	                   BcVec4d( Side.z(),		Up.z(),		-Front.z(),		0.0f ),
	                   BcVec4d( 0.0f,			0.0f,			0.0f,		1.0f ) );

	BcMat4d TransMatrix( BcVec4d( 1.0f,			0.0f,			0.0f,		0.0f ),
	                   BcVec4d( 0.0f,			1.0f,			0.0f,		0.0f ),
	                   BcVec4d( 0.0f,			0.0f,			1.0f,		0.0f ),
	                   BcVec4d( -Position.x(), -Position.y(), -Position.z(),  1.0f ) );

	(*this) = TransMatrix * RotMatrix;
}
Esempio n. 6
0
int
APITestUtil::MakeTest2RailSweepSurface(NURBSSet &nset)
{
	int rail1 = P1Curve(nset, ScaleMatrix(Point3(70, 70, 70)));
	int rail2 = P1Curve(nset, ScaleMatrix(Point3(90, 90, 90)));
	int cross = P1Curve(nset, ScaleMatrix(Point3(5, 5, 5)) *
							RotateYMatrix(PI/2.0f) *
							TransMatrix(Point3(70, 70, 0)));
	NURBS2RailSweepSurface *s = new NURBS2RailSweepSurface();
	s->SetName(GetString(IDS_2RAIL_SURFACE));
	s->SetNSet(&nset);

	s->SetRailParent(0, rail1);
	s->SetRailParent(1, rail2);
	s->AppendCurve(cross, FALSE);

	return nset.AppendObject(s);
}
Esempio n. 7
0
int
APITestUtil::MakeTest1RailSweepSurface(NURBSSet &nset)
{
	int rail = P1Curve(nset, ScaleMatrix(Point3(50, 50, 50)));
	int cross = P1Curve(nset, ScaleMatrix(Point3(5, 5, 5)) *
							RotateYMatrix(PI/2.0f) *
							TransMatrix(Point3(50, 50, 0)));
	NURBS1RailSweepSurface *s = new NURBS1RailSweepSurface();
	s->SetName(GetString(IDS_1RAIL_SURFACE));
	s->SetNSet(&nset);

	s->SetParentRail(rail);
	s->AppendCurve(cross, FALSE);
	s->SetParallel(FALSE);
	s->FlipNormals(TRUE);

	return nset.AppendObject(s);
}
Esempio n. 8
0
int
APITestUtil::MakeTestMultiCurveTrimSurface(NURBSSet &nset)
{
	int srf = MakeTestCVSurface(nset, TransMatrix(Point3(100, 100, 150)));
	int cos1 = COS1(nset, srf);
	int cos2 = COS2(nset, srf);

	NURBSMultiCurveTrimSurface *s = new NURBSMultiCurveTrimSurface();
	s->SetName(GetString(IDS_MULTI_TRIM_SURFACE));
	s->SetNSet(&nset);

	s->SetSurfaceParent(srf);
	s->AppendCurve(cos1);
	s->AppendCurve(cos2);

    // Tell the surface to flip the orientation of the trim.
	s->SetFlipTrim(TRUE);

	return nset.AppendObject(s);
}
Esempio n. 9
0
void
APITestUtil::CombinedTests()
{
	// now let's build a test object
	NURBSSet nset;
	Matrix3 mat;
	mat.IdentityMatrix();


	// build an independent point
	int indPnt = MakeTestPoint(nset);

	// now a constrained point
	int ptPnt = MakeTestPointCPoint(nset, indPnt);



	// build a cv curve
	int cvCrv = MakeTestCVCurve(nset, mat);

	// and a constrained point on that curve
	int crvPnt = MakeTestCurveCPoint(nset, cvCrv);

	// now a point curve
	int ptCrv = MakeTestPointCurve(nset, mat);

	// Blend the two curves
	int blendCrv = MakeTestBlendCurve(nset, cvCrv, ptCrv);

	// make an offset of the CV curve
	int offCrv = MakeTestOffsetCurve(nset, cvCrv);

	// make a Transform curve of the point curve
	int xformCrv = MakeTestXFormCurve(nset, ptCrv);

	// make a mirror of the blend
	int mirCrv = MakeTestMirrorCurve(nset, blendCrv);

	// make a fillet curve (It makes it's own point curves to fillet)
	int fltCrv = MakeTestFilletCurve(nset);

	// make a chamfer curve (It makes it's own point curves to fillet)
	int chmCrv = MakeTestChamferCurve(nset);




	// build a cv surface
	int cvSurf = MakeTestCVSurface(nset, mat);


	// and a constrained point on that surface
	int srfPnt = MakeTestSurfCPoint(nset, cvSurf);

	// Curve Surface intersection point.
	int cvCrv2 = MakeTestCVCurve(nset, RotateXMatrix(PI/2.0f) * TransMatrix(Point3(0, 0, -175)));
	int srfIntPoint = MakeTestCurveSurface(nset, cvSurf, cvCrv2);

	// Now an Iso Curve on the CV surface
	int isoCrv1 = MakeTestIsoCurveU(nset, cvSurf);

	// Now an Iso Curve on the CV surface
	int isoCrv2 = MakeTestIsoCurveV(nset, cvSurf);

	// Now a Surface Edge Curve on the CV surface
	int surfEdgeCrv = MakeTestSurfaceEdgeCurve(nset, cvSurf);

	// build a CV Curve on Surface
	int cvCOS = MakeTestCurveOnSurface(nset, cvSurf);

	// build a Point Curve on Surface
	int pntCOS = MakeTestPointCurveOnSurface(nset, cvSurf);

	// build a Surface Normal Offset Curve
	int cnoCrf = MakeTestSurfaceNormalCurve(nset, cvCOS);

    // Make a curve-curve intersection point
    int curveCurve = MakeTestCurveCurve(nset, isoCrv1, isoCrv2, TRUE);

	// build a point surface
	int ptSurf = MakeTestPointSurface(nset, mat);

	// Blend the two surfaces
	int blendSurf = MakeTestBlendSurface(nset, cvSurf, ptSurf);

	// Offset of the blend
	int offSurf = MakeTestOffsetSurface(nset, blendSurf);

	// Transform of the Offset
	int xformSurf = MakeTestXFormSurface(nset, offSurf);

	// Mirror of the transform surface
	int mirSurf = MakeTestMirrorSurface(nset, xformSurf);

	// Make a Ruled surface between two curves
	int rulSurf = MakeTestRuledSurface(nset, cvCrv, ptCrv);

	// Make a ULoft surface
	int uLoftSurf = MakeTestULoftSurface(nset, ptCrv, offCrv, xformCrv);

	// Make a Extrude surface
	int extSurf = MakeTestExtrudeSurface(nset, xformCrv);

	// Make a lathe
	int lthSurf = MakeTestLatheSurface(nset);

	// these will build their own curves to work with
	// UV Loft
	int uvLoftSurf = MakeTestUVLoftSurface(nset);


	// 1 Rail Sweep
	int oneRailSurf = MakeTest1RailSweepSurface(nset);

	// 2 Rail Sweep
	int twoRailSurf = MakeTest2RailSweepSurface(nset);

	// MultiCurveTrim Surface
	int multiTrimSurf = MakeTestMultiCurveTrimSurface(nset);


	// Now make the curves and surfaces that we'll use later for the join tests
	int jc1, jc2, js1, js2;
	AddObjectsForJoinTests(nset, jc1, jc2, js1, js2);

	int bc, bs;
	AddObjectsForBreakTests(nset, bc, bs);


	Object *obj = CreateNURBSObject(mpIp, &nset, mat);
	INode *node = mpIp->CreateObjectNode(obj);
	node->SetName(GetString(IDS_TEST_OBJECT));




	NURBSSet addNset;
	// build a point surface
	int addptSurf = AddTestPointSurface(addNset);

	// add an iso curve to the previously created CV Surface
	NURBSId id = nset.GetNURBSObject(cvSurf)->GetId();
	int addIsoCrv = AddTestIsoCurve(addNset, id);

	AddNURBSObjects(obj, mpIp, &addNset);




	// now test some changing functionality
	// Let's change the name of the CVSurface
	NURBSObject* nObj = nset.GetNURBSObject(cvSurf);
	nObj->SetName(_T("New CVSurf Name"));  // testing only, no need to localize

	// now let's change the position of one of the points in the point curve
	NURBSPointCurve* ptCrvObj = (NURBSPointCurve*)nset.GetNURBSObject(ptCrv);
	ptCrvObj->GetPoint(0)->SetPosition(0, Point3(10, 160, 0)); // moved from 0,150,0

	// now let's change the position and weight of one of the CVs
	// in the CV Surface
	NURBSCVSurface* cvSurfObj = (NURBSCVSurface*)nset.GetNURBSObject(cvSurf);
	cvSurfObj->GetCV(0, 0)->SetPosition(0, Point3(-150.0, -100.0, 20.0)); // moved from 0,0,0
	cvSurfObj->GetCV(0, 0)->SetWeight(0, 2.0); // from 1.0


	// now let's do a transform of a curve.
	NURBSIdTab xfmTab;
	NURBSId nid = nset.GetNURBSObject(jc1)->GetId();
	xfmTab.Append(1, &nid);
	Matrix3 xfmMat;
	xfmMat = TransMatrix(Point3(10, 10, -10));
	SetXFormPacket xPack(xfmMat);
	NURBSResult res = Transform(obj, xfmTab, xPack, xfmMat, 0);




	// Now let's Join two curves
	NURBSId jc1id = nset.GetNURBSObject(jc1)->GetId(),
			jc2id = nset.GetNURBSObject(jc2)->GetId();
	JoinCurves(obj, jc1id, jc2id, FALSE, TRUE, 20.0, 1.0f, 1.0f, 0);

	// Now let's Join two surfaces
	NURBSId js1id = nset.GetNURBSObject(js1)->GetId(),
			js2id = nset.GetNURBSObject(js2)->GetId();
	JoinSurfaces(obj, js1id, js2id, 1, 0, 20.0, 1.0f, 1.0f, 0);

	// Break a Curve
	NURBSId bcid = nset.GetNURBSObject(bc)->GetId();
	BreakCurve(obj, bcid, .5, 0);

	// Break a Surface
	NURBSId bsid = nset.GetNURBSObject(bs)->GetId();
	BreakSurface(obj, bsid, TRUE, .5, 0);

	mpIp->RedrawViews(mpIp->GetTime());
	nset.DeleteObjects();
	addNset.DeleteObjects();


	// now do a detach
	NURBSSet detset;
	Matrix3 detmat;
	detmat.IdentityMatrix();
	// build a cv curve
	int detcvCrv = MakeTestCVCurve(detset, detmat);

	// now a point curve
	int detptCrv = MakeTestPointCurve(detset, detmat);

	// Blend the two curves
	int detblendCrv = MakeTestBlendCurve(detset, detcvCrv, detptCrv);

	Object *detobj = CreateNURBSObject(mpIp, &detset, detmat);
	INode *detnode = mpIp->CreateObjectNode(detobj);
	detnode->SetName("Detach From");

	BOOL copy = TRUE;
	BOOL relational = TRUE;
	NURBSIdList detlist;
	NURBSId oid = detset.GetNURBSObject(detblendCrv)->GetId();
	detlist.Append(1, &oid);
	DetachObjects(GetCOREInterface()->GetTime(), detnode, detobj,
					detlist, "Detach Test", copy, relational);
	mpIp->RedrawViews(mpIp->GetTime());

}
Esempio n. 10
0
void sphere()
{    
    SetGeomScreen(1000);     
    MATRIX m;
    VECTOR trans = {0, 0, 300};
    TransMatrix(&m, &trans);
    SetTransMatrix(&m);      
    const int SPHERE_LATITUDE = 24;
    const int SPHERE_LONGITUDE = 24;
    const int SPHERE_RADIUS = 50;
    SVECTOR* sphere_vector = (SVECTOR*)MemoryManager::malloc(SPHERE_LATITUDE * SPHERE_LONGITUDE * sizeof(*sphere_vector));   
    POLY_G4* poly_sphere = (POLY_G4*)MemoryManager::malloc(SPHERE_LATITUDE * SPHERE_LONGITUDE * sizeof(*poly_sphere));
    {
        /**
         *  x <- r * sin(\alpha) * cos(\beta)
         *  y <- r * sin(\alpha) * sin(\beta)
         *  z <- r * cos(\alpha)
         * avec:
         *   \alpha \in [0, pi] : latitude
         *   \beta \in [0, 2*pi] : longitude
         */ 
        SVECTOR* v = sphere_vector;
        for ( int la = 0; la < SPHERE_LATITUDE; la++ ) {
            int alpha = (TRIGO_PI * la) / SPHERE_LATITUDE;
            int sa = sin4k[alpha];
            int ca = cos4k[alpha];
            for ( int lo = 0; lo < SPHERE_LONGITUDE; lo++, v++ ) {
                int beta = (2 * TRIGO_PI * lo) / SPHERE_LONGITUDE;
                unsigned short x = (SPHERE_RADIUS * sa * cos4k[beta]) / (TRIGO_SCALE * TRIGO_SCALE);
                unsigned short y = (SPHERE_RADIUS * sa * sin4k[beta]) / (TRIGO_SCALE *TRIGO_SCALE);
                unsigned short z = (SPHERE_RADIUS * ca) / TRIGO_SCALE;
                setVector(v, x, y, z);             
            }            
        }
        POLY_G4* p = poly_sphere;        
        for ( int la = 0; la < SPHERE_LATITUDE; la++ ) {
            for ( int lo = 0; lo < SPHERE_LONGITUDE; lo++, p++ ) {
                SetPolyG4(p);
            }
        }        
    }
    set_clear_color(0);
    static const int SPHERE_TRANSITION_STEP = 200;
    static const int SPHERE_STEP_TIME = 600;
            
    enum { SCENE_LAT_FLAT = 1, 
           SCENE_LAT_SMOOTH,
           SCENE_LIGHT_FIX_EDGE,
           SCENE_LIGHT_FIX_SQUARE,
           SCENE_LIGHT_FIX,
           SCENE_LIGHT_MOVE,
           SCENE_LIGHT_CUTOFF,
           SCENE_ZOOM,
           SCENE_LIGHT_SINUS_WAVE, };
    int current_scene = SCENE_LAT_FLAT;
    int t = 0;
    enable_auto_clear_color_buffer();    
    while ( t < SCENE_LIGHT_SINUS_WAVE * SPHERE_STEP_TIME)
    {
        SVECTOR rot = {8*t%4096, 4*t%4096, 10*t%4096};
        RotMatrix(&rot, &m);
        SetRotMatrix(&m);
        
        // update sphere    
        POLY_G4* p = poly_sphere;        
        
        // offset plasma
        static int off = 0; 
        if ( t >= 100 && t % 5 == 0 ) off++;  
                
        // light move
        static int light_move_lat = 0;
        static int light_move_long = 0;
        static int light_move_dlat = 1;
        static int light_move_dlong = 1;           
        if ( t % 1 == 0 ) {
            if ( t % 3 == 0 ) {
                light_move_lat += light_move_dlat; 
                if ( light_move_lat < 0 ) light_move_lat = 0; 
                if ( light_move_lat >= SPHERE_LATITUDE ) light_move_lat = SPHERE_LATITUDE-1;
                if ( light_move_lat == 0 || light_move_lat == SPHERE_LATITUDE-1 ) light_move_dlat *= -1;
            }
            if ( t % 1 == 0 ) {
                light_move_long += light_move_dlong; 
                if ( light_move_long < 0 ) light_move_long = 0; 
                if ( light_move_long >= SPHERE_LONGITUDE ) light_move_long = SPHERE_LONGITUDE-1;
                if ( light_move_long == 0 || light_move_long == SPHERE_LONGITUDE-1 ) light_move_long *= -1;
            }
        }     

        // dynamic cutoff
        static int light_dynamic_distance_max = 50;        
        if ( current_scene == SCENE_LIGHT_CUTOFF && t % 1 == 0 ) {            
            static const int LIGHT_DYNAMIC_DISTANCE_MIN = 20;
            static const int LIGHT_DYNAMIC_DISTANCE_MAX = 60;
            static int light_dynamic_ddist = -1;
            light_dynamic_distance_max += light_dynamic_ddist;
            if ( light_dynamic_distance_max <= LIGHT_DYNAMIC_DISTANCE_MIN || light_dynamic_distance_max >= LIGHT_DYNAMIC_DISTANCE_MAX ) light_dynamic_ddist *= -1;
        }
        int light_dynamic_distance_max2 = light_dynamic_distance_max * light_dynamic_distance_max;   
        
        // dynamic radius         
        if ( current_scene >= SCENE_ZOOM && t % 1 == 0 ) {                        
            static const int ZOOM_MIN = 150;
            static const int ZOOM_MAX = 900;
            static int zoom_stride = 15;
            static int zoom = 300;            
            SetGeomScreen(zoom);            
            zoom += zoom_stride;
            if ( zoom <= ZOOM_MIN || zoom >= ZOOM_MAX ) zoom_stride *= -1;
        }        
                
        int dt = 1;
        for ( int la = 0; la < SPHERE_LATITUDE; la++ ) {
            for ( int lo = 0; lo < SPHERE_LONGITUDE; lo++, p++ ) {                
                int lo_next = (lo+1)%SPHERE_LONGITUDE;
                int la_next = SignalProcessing::min(la+1, SPHERE_LATITUDE-1);                
                SVECTOR* v0 = &sphere_vector[la*SPHERE_LONGITUDE+lo];
                SVECTOR* v1 = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                SVECTOR* v2 = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];
                SVECTOR* v3 = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                
                long dmy, flag;
                int otz = 0;
                otz += RotTransPers(v0, (long*)&p->x0, &dmy, &flag);                 
                otz += RotTransPers(v1, (long*)&p->x1, &dmy, &flag);                 
                otz += RotTransPers(v2, (long*)&p->x2, &dmy, &flag);                
                otz += RotTransPers(v3, (long*)&p->x3, &dmy, &flag);
                otz /= 4;
                limitRange(otz, 0, OT_LENGTH-1);
                AddPrim(ot + OT_LENGTH - 1 - otz, p);                
                if ( t < SCENE_LAT_FLAT*SPHERE_STEP_TIME ) { // latitude same flat color
                    current_scene = SCENE_LAT_FLAT;
                    unsigned char b = 255 * la / SPHERE_LATITUDE;                     
                    setRGB0(p, b, b, b);
                    setRGB1(p, b, b, b);
                    setRGB2(p, b, b, b);
                    setRGB3(p, b, b, b);
                } else if ( t < SCENE_LAT_SMOOTH*SPHERE_STEP_TIME ) { // latitude same smooth color
                    current_scene = SCENE_LAT_SMOOTH;
                    unsigned char b = 255 * la / SPHERE_LATITUDE;  
                    unsigned char bb = 255 * ((la+1)%SPHERE_LATITUDE) / SPHERE_LATITUDE;
                    if ( t < (SCENE_LAT_SMOOTH-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB1(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB3(p, bb, bb, bb);
                } else if ( t < SCENE_LIGHT_FIX_EDGE*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting fix
                    dt = 3;
                    current_scene = SCENE_LIGHT_FIX_EDGE;
                    unsigned char b = 255;
                    unsigned char bb = 255;
                    const int LIGHT_LAT = 3*SPHERE_LATITUDE/4;
                    const int LIGHT_LONG = SPHERE_LONGITUDE/4;
                    const int LIGHT_DISTANCE_MAX = 50;
                    const int LIGHT_DISTANCE_MAX2 = LIGHT_DISTANCE_MAX * LIGHT_DISTANCE_MAX;
                    SVECTOR* l = &sphere_vector[LIGHT_LAT*SPHERE_LONGITUDE+LIGHT_LONG];
                    SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];
                    SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];
                    int d = SignalProcessing::dist2(l, v);
                    int dd = SignalProcessing::dist2(l, vv);
                    b = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - d) * b) / LIGHT_DISTANCE_MAX2;
                    bb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dd) * bb) / LIGHT_DISTANCE_MAX2;
                    // smooth
                    if ( t < (SCENE_LIGHT_FIX-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB1(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB3(p, bb, bb, bb);
                } else if ( t < SCENE_LIGHT_FIX_SQUARE*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting fix
                    dt = 3;
                    current_scene = SCENE_LIGHT_FIX_SQUARE;
                    unsigned char b = 255;
                    unsigned char bb = 255;
                    unsigned char bbb = 255;
                    unsigned char bbbb = 255;
                    const int LIGHT_LAT = 3*SPHERE_LATITUDE/4;
                    const int LIGHT_LONG = SPHERE_LONGITUDE/4;
                    const int LIGHT_DISTANCE_MAX = 50;
                    const int LIGHT_DISTANCE_MAX2 = LIGHT_DISTANCE_MAX * LIGHT_DISTANCE_MAX;
                    SVECTOR* l = &sphere_vector[LIGHT_LAT*SPHERE_LONGITUDE+LIGHT_LONG];
                    SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                    SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                    SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                    SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                    int d = SignalProcessing::dist2(l, v);
                    int dd = SignalProcessing::dist2(l, vv);
                    int ddd = SignalProcessing::dist2(l, vvv);
                    int dddd = SignalProcessing::dist2(l, vvvv);
                    b = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - d) * b) / LIGHT_DISTANCE_MAX2;
                    bb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dd) * bb) / LIGHT_DISTANCE_MAX2;
                    bbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - ddd) * bbb) / LIGHT_DISTANCE_MAX2;
                    bbbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - dddd) * bbbb) / LIGHT_DISTANCE_MAX2;                    
                    // smooth
                    if ( t < (SCENE_LIGHT_FIX-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB1(p, bb, bb, bb);
                    setRGB2(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);                     
                } else if ( t < SCENE_LIGHT_FIX*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting fix
                    dt = 1;
                    current_scene = SCENE_LIGHT_FIX;
                    unsigned char b = 255;
                    unsigned char bb = 255;
                    unsigned char bbb = 255;
                    unsigned char bbbb = 255;
                    const int LIGHT_LAT = 3*SPHERE_LATITUDE/4;
                    const int LIGHT_LONG = SPHERE_LONGITUDE/4;
                    const int LIGHT_DISTANCE_MAX = 50;
                    const int LIGHT_DISTANCE_MAX2 = LIGHT_DISTANCE_MAX * LIGHT_DISTANCE_MAX;
                    SVECTOR* l = &sphere_vector[LIGHT_LAT*SPHERE_LONGITUDE+LIGHT_LONG];
                    SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                    SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                    SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                    SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                    int d = SignalProcessing::dist2(l, v);
                    int dd = SignalProcessing::dist2(l, vv);
                    int ddd = SignalProcessing::dist2(l, vvv);
                    int dddd = SignalProcessing::dist2(l, vvvv);
                    b = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - d) * b) / LIGHT_DISTANCE_MAX2;
                    bb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dd) * bb) / LIGHT_DISTANCE_MAX2;
                    bbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - ddd) * bbb) / LIGHT_DISTANCE_MAX2;
                    bbbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - dddd) * bbbb) / LIGHT_DISTANCE_MAX2;                    
                    // smooth
                    if ( t < (SCENE_LIGHT_FIX-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r1 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r3 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB1(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);                    
                } else if ( t < SCENE_LIGHT_MOVE*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting move
                    current_scene = SCENE_LIGHT_MOVE;
                    unsigned char b = 255;
                    unsigned char bb = 255;                    
                    unsigned char bbb = 255;                    
                    unsigned char bbbb = 255;                    
                    const int LIGHT_DISTANCE_MAX = 50;
                    const int LIGHT_DISTANCE_MAX2 = LIGHT_DISTANCE_MAX * LIGHT_DISTANCE_MAX;
                    // light
                    {
                        SVECTOR* l = &sphere_vector[light_move_lat*SPHERE_LONGITUDE+light_move_long];
                        SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                        SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                        int d = SignalProcessing::dist2(l, v);
                        int dd = SignalProcessing::dist2(l, vv);
                        int ddd = SignalProcessing::dist2(l, vvv);
                        int dddd = SignalProcessing::dist2(l, vvvv);
                        b = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - d) * b) / LIGHT_DISTANCE_MAX2;
                        bb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dd) * bb) / LIGHT_DISTANCE_MAX2;
                        bbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - ddd) * bbb) / LIGHT_DISTANCE_MAX2;
                        bbbb = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - dddd) * bbbb) / LIGHT_DISTANCE_MAX2;                       
                    }
                    // smooth
                    if ( t < (SCENE_LIGHT_MOVE-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r1 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r3 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB1(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);      
                } else if ( t < SCENE_LIGHT_CUTOFF*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting move + dynamic cutoff 
                    current_scene = SCENE_LIGHT_CUTOFF;
                    unsigned char b = 255;
                    unsigned char bb = 255;
                    unsigned char bbb = 255;
                    unsigned char bbbb = 255;
                    // light
                    {
                        SVECTOR* l = &sphere_vector[light_move_lat*SPHERE_LONGITUDE+light_move_long];
                        SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                        SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                        int d = SignalProcessing::dist2(l, v);
                        int dd = SignalProcessing::dist2(l, vv);
                        int ddd = SignalProcessing::dist2(l, vvv);
                        int dddd = SignalProcessing::dist2(l, vvvv);
                        b = (SignalProcessing::max(0, light_dynamic_distance_max2 - d) * b) / light_dynamic_distance_max2;
                        bb = (SignalProcessing::max(0,  light_dynamic_distance_max2 - dd) * bb) / light_dynamic_distance_max2;                    
                        bbb = (SignalProcessing::max(0, light_dynamic_distance_max2 - ddd) * bbb) / light_dynamic_distance_max2;
                        bbbb = (SignalProcessing::max(0, light_dynamic_distance_max2 - dddd) * bbbb) / light_dynamic_distance_max2;
                    }
                    // smooth
                    if ( t < (SCENE_LIGHT_CUTOFF-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r1 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r3 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB1(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);     
                } else if ( t < SCENE_ZOOM*SPHERE_STEP_TIME ) { // latitude same smooth color + lighting move + dynamic cutoff + zoom
                    current_scene = SCENE_ZOOM;
                    unsigned char b = 255;
                    unsigned char bb = 255;
                    unsigned char bbb = 255;
                    unsigned char bbbb = 255;
                    // light
                    {
                        SVECTOR* l = &sphere_vector[light_move_lat*SPHERE_LONGITUDE+light_move_long];
                        SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                        SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                        int d = SignalProcessing::dist2(l, v);
                        int dd = SignalProcessing::dist2(l, vv);
                        int ddd = SignalProcessing::dist2(l, vvv);
                        int dddd = SignalProcessing::dist2(l, vvvv);
                        b = (SignalProcessing::max(0, light_dynamic_distance_max2 - d) * b) / light_dynamic_distance_max2;
                        bb = (SignalProcessing::max(0,  light_dynamic_distance_max2 - dd) * bb) / light_dynamic_distance_max2;                    
                        bbb = (SignalProcessing::max(0, light_dynamic_distance_max2 - ddd) * bbb) / light_dynamic_distance_max2;
                        bbbb = (SignalProcessing::max(0, light_dynamic_distance_max2 - dddd) * bbbb) / light_dynamic_distance_max2;                   
                    }
                    // smooth
                    if ( t < (SCENE_ZOOM-1)*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r1 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r3 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB1(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);
                }                 
                else { // smooth bande move + lighting move
                    current_scene = SCENE_LIGHT_SINUS_WAVE;
                    const int LIGHT_DISTANCE_MAX = 50;
                    const int LIGHT_DISTANCE_MAX2 = LIGHT_DISTANCE_MAX * LIGHT_DISTANCE_MAX;
                    const int NB_COLOR = 5;                    
                    unsigned char b = (255 * (((la+off)%SPHERE_LATITUDE)%NB_COLOR)) / (NB_COLOR-1);
                    unsigned char bb = (255 * (((la+1+off)%SPHERE_LATITUDE)%NB_COLOR)) / (NB_COLOR-1);
                    unsigned char bbb = (255 * (((la+off)%SPHERE_LATITUDE)%NB_COLOR)) / (NB_COLOR-1);
                    unsigned char bbbb = (255 * (((la+1+off)%SPHERE_LATITUDE)%NB_COLOR)) / (NB_COLOR-1);
                    // light
                    {
                        SVECTOR* l = &sphere_vector[light_move_lat*SPHERE_LONGITUDE+light_move_long];
                        SVECTOR* v = &sphere_vector[la*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo];                    
                        SVECTOR* vvv = &sphere_vector[la*SPHERE_LONGITUDE+lo_next];
                        SVECTOR* vvvv = &sphere_vector[la_next*SPHERE_LONGITUDE+lo_next];
                        int d = SignalProcessing::dist2(l, v);
                        int dd = SignalProcessing::dist2(l, vv);
                        int ddd = SignalProcessing::dist2(l, vvv);
                        int dddd = SignalProcessing::dist2(l, vvvv);
                        b = (SignalProcessing::max(0, LIGHT_DISTANCE_MAX2 - d) * b) / LIGHT_DISTANCE_MAX2;
                        bb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dd) * bb) / LIGHT_DISTANCE_MAX2; 
                        bbb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - ddd) * bbb) / LIGHT_DISTANCE_MAX2; 
                        bbbb = (SignalProcessing::max(0,  LIGHT_DISTANCE_MAX2 - dddd) * bbbb) / LIGHT_DISTANCE_MAX2; 
                    }
                    // smooth
                    if ( t < 5*SPHERE_STEP_TIME + SPHERE_TRANSITION_STEP ) {
                        int d= (t%SPHERE_TRANSITION_STEP);
                        b = (b * d + p->r0 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bb = (bb * d + p->r2 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbb = (bbb * d + p->r1 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                        bbbb = (bbbb * d + p->r3 * (SPHERE_TRANSITION_STEP - d)) / SPHERE_TRANSITION_STEP;
                    } 
                    setRGB0(p, b, b, b);
                    setRGB2(p, bb, bb, bb);
                    setRGB1(p, bbb, bbb, bbb);
                    setRGB3(p, bbbb, bbbb, bbbb);
                }                
            }
        }        
        display();
        t += dt;
    }    
    MemoryManager::free(sphere_vector);    
    MemoryManager::free(poly_sphere);    
}
Esempio n. 11
0
void ExtrudeMod::BuildMeshFromShape(TimeValue t,ModContext &mc, ObjectState * os, Mesh &mesh, BOOL simple) {
	BOOL texturing;
	pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER);
	BOOL genMatIDs;
	pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIDs, FOREVER);
	BOOL useShapeIDs;
	pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER);
	BOOL smooth;
	pblock->GetValue(PB_SMOOTH, TimeValue(0), smooth, FOREVER);

	ShapeObject *shape = (ShapeObject *)os->obj;

	float amount;
	int levels,capStart,capEnd,capType;

	pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
	if(simple) {
		levels = 1;
		capStart = capEnd = FALSE;
		}
	else {
		pblock->GetValue(PB_SEGS,t,levels,FOREVER);
		if (levels<1) levels = 1;
		pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER);
		pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER);
		}
	pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER);

	LimitValue(amount, -1000000.0f, 1000000.0f);

	// Get the basic dimension stuff
	float zSize = (float)fabs(amount);
	float baseZ = 0.0f;
	if(amount < 0.0f)
		baseZ = amount;

	// Make the shape convert itself to a PolyShape -- This makes our mesh conversion MUCH easier!
	
	PolyShape pShape;
	shape->MakePolyShape(t, pShape);
	ShapeHierarchy hier;
	pShape.OrganizeCurves(t, &hier);
	// Need to flip the reversed curves in the shape!
	pShape.Reverse(hier.reverse);

	int polys = pShape.numLines;
	int levelVerts = 0, levelFaces = 0, levelTVerts = 0;
	int verts = 0, faces = 0, tVerts = 0;
	int poly, piece;

	BOOL anyClosed = FALSE;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		if(line.IsClosed()) {
			anyClosed = TRUE;
			levelTVerts++;
			}
		levelVerts += line.numPts;
		levelTVerts += line.numPts;
		levelFaces += (line.Segments() * 2);
		}

	int vertsPerLevel = levelVerts;
	int numLevels = levels;

	verts = levelVerts * (levels + 1);
	tVerts = levelTVerts * (levels + 1);
	faces = levelFaces * levels;

	mesh.setNumVerts(verts);
	mesh.setNumFaces(faces);
	if(texturing) {
		mesh.setNumTVerts(tVerts);
		mesh.setNumTVFaces(faces);
		}

	// Create the vertices!
	int vert = 0;
	int tvertex = 0;
	int level;
	Point3 offset1, offset2;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		if(texturing) {
//DebugPrint(_T("Texture Verts:\n"));
            BOOL usePhysUVs = GetUsePhysicalScaleUVs();
			int tp;
			int texPts = line.numPts + (line.IsClosed() ? 1 : 0);
			float *texPt = new float [texPts];
			float lastPt = (float)(texPts - 1);
			float cumLen = 0.0f;
			float totLen = line.CurveLength();
			Point3 prevPt = line.pts[0].p;
			for(tp = 0; tp < texPts; ++tp) {
				int ltp = tp % line.numPts;
				if(tp == (texPts - 1))
					texPt[tp] = usePhysUVs ? totLen : 1.0f;
				else {
					Point3 &pt = line.pts[ltp].p;
					cumLen += Length(pt - prevPt);
                    if (usePhysUVs)
                        texPt[tp] = cumLen;
                    else
					texPt[tp] = cumLen / totLen;
					prevPt = pt;
					}
				}
			float flevels = (float)levels;
			for(level = 0; level <= levels; ++level) {
				float tV = (float)level / flevels;
                float vScale = usePhysUVs ? amount : 1.0f;
				for(tp = 0; tp < texPts; ++tp) {
					mesh.setTVert(tvertex++, UVVert(texPt[tp], vScale*tV, 0.0f));
					}
				}
			delete [] texPt;
			}
		int lverts = line.numPts;
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			if(level == 0)
				offset1 = offset;
			else
			if(level == levels)
				offset2 = offset;
			for(int v = 0; v < lverts; ++v) {
				line.pts[v].aux = vert;			// Gives the capper this vert's location in the mesh!
				mesh.setVert(vert++, line.pts[v].p + offset);
				}
			}
		}
	assert(vert == verts);

	// If capping, do it!
	if(anyClosed && (capStart || capEnd)) {
		MeshCapInfo capInfo;
		pShape.MakeCap(t, capInfo, capType);
		// Build information for capping
		MeshCapper capper(pShape);
		if(capStart) {
			vert = 0;
			for(poly = 0; poly < polys; ++poly) {
				PolyLine &line = pShape.lines[poly];
				if(!line.numPts)
					continue;
				MeshCapPoly &capline = capper[poly];
				int lverts = line.numPts;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				vert += lverts * levels;
				}
			// Create a work matrix for grid capping
			Matrix3 gridMat = TransMatrix(offset1);
			int oldFaces = mesh.numFaces;
			capper.CapMesh(mesh, capInfo, TRUE, 16, &gridMat, genMatIDs ? -1 : 0);
			// If texturing, create the texture faces and vertices
			if(texturing)
				MakeMeshCapTexture(mesh, Inverse(gridMat), oldFaces, mesh.numFaces, GetUsePhysicalScaleUVs());
			}
		if(capEnd) {
			int baseVert = 0;
			for(poly = 0; poly < polys; ++poly) {
				PolyLine &line = pShape.lines[poly];
				if(!line.numPts)
					continue;
				MeshCapPoly &capline = capper[poly];
				int lverts = line.numPts;
				vert = baseVert + lverts * levels;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				baseVert += lverts * (levels + 1);
				}
			// Create a work matrix for grid capping
			Matrix3 gridMat = TransMatrix(offset2);
			int oldFaces = mesh.numFaces;
			capper.CapMesh(mesh, capInfo, FALSE, 16, &gridMat, genMatIDs ? -1 : 0);
			// If texturing, create the texture faces and vertices
			if(texturing)
				MakeMeshCapTexture(mesh, Inverse(gridMat), oldFaces, mesh.numFaces, GetUsePhysicalScaleUVs());
			}
		}

	// Create the faces!
	int face = 0;
	int TVface = 0;
	int baseVert = 0;
	int baseTVert = 0;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		int pieces = line.Segments();
		int closed = line.IsClosed();
		int segVerts = pieces + ((closed) ? 0 : 1);
		int segTVerts = pieces + 1;
		for(level = 0; level < levels; ++level) {
			int sm = 0;		// Initial smoothing group
			BOOL firstSmooth = (line.pts[0].flags & POLYPT_SMOOTH) ? TRUE : FALSE;
			for(piece = 0; piece < pieces; ++piece) {
				int v1 = baseVert + piece;
				int v2 = baseVert + ((piece + 1) % segVerts);
				int v3 = v1 + segVerts;
				int v4 = v2 + segVerts;
				// If the vertex is not smooth, go to the next group!
				BOOL thisSmooth = line.pts[piece].flags & POLYPT_SMOOTH;
				MtlID mtl = useShapeIDs ? line.pts[piece].GetMatID() : 2;
				if(piece > 0 && !thisSmooth) {
					sm++;
					if(sm > 2)
						sm = 1;
					}
				DWORD smoothGroup = 1 << sm;
				// Advance to the next smoothing group right away
				if(sm == 0)
					sm++;
				// Special case for smoothing from first segment
				if(piece == 1 && thisSmooth)
					smoothGroup |= 1;
				// Special case for smoothing from last segment
				if((piece == pieces - 1) && firstSmooth)
					smoothGroup |= 1;
				mesh.faces[face].setEdgeVisFlags(1,1,0);
				mesh.faces[face].setSmGroup(smooth ? smoothGroup : 0);
				mesh.faces[face].setMatID(genMatIDs ? mtl : 0);
				mesh.faces[face++].setVerts(v1, v2, v4);
				mesh.faces[face].setEdgeVisFlags(0,1,1);
				mesh.faces[face].setSmGroup(smooth ? smoothGroup : 0);
				mesh.faces[face].setMatID(genMatIDs ? mtl : 0);
				mesh.faces[face++].setVerts(v1, v4, v3);
//DebugPrint(_T("BV:%d V:%d v1:%d v2:%d v3:%d v4:%d\n"),baseVert, vert, v1, v2, v3, v4);
				if(texturing) {
					int tv1 = baseTVert + piece;
					int tv2 = tv1 + 1;
					int tv3 = tv1 + segTVerts;
					int tv4 = tv2 + segTVerts;
					mesh.tvFace[TVface++].setTVerts(tv1, tv2, tv4);
					mesh.tvFace[TVface++].setTVerts(tv1, tv4, tv3);
					}
				}
			baseVert += segVerts;
			baseTVert += segTVerts;
			}
		baseVert += segVerts;	// Increment to next poly start (skips last verts of this poly)
		baseTVert += segTVerts;
		}
	assert(face == faces);

	mesh.InvalidateGeomCache();
	}
Esempio n. 12
0
void ExtrudeMod::BuildPatchFromShape(TimeValue t,ModContext &mc, ObjectState * os, PatchMesh &pmesh) {
	ShapeObject *shape = (ShapeObject *)os->obj;

	float amount;
	int levels,capStart,capEnd,capType;

	pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
	pblock->GetValue(PB_SEGS,t,levels,FOREVER);
	if (levels<1) levels = 1;
	pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER);
	pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER);
	pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER);

	BOOL texturing;
	pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER);
	BOOL genMatIDs;
	pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIDs, FOREVER);
	BOOL useShapeIDs;
	pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER);
	BOOL smooth;
	pblock->GetValue(PB_SMOOTH, TimeValue(0), smooth, FOREVER);

	LimitValue(amount, -1000000.0f, 1000000.0f);

	// Get the basic dimension stuff
	float zSize = (float)fabs(amount);
	float baseZ = 0.0f;
	if(amount < 0.0f)
		baseZ = amount;

	// If the shape can convert itself to a BezierShape, have it do so!
	BezierShape bShape;
	if(shape->CanMakeBezier())
		shape->MakeBezier(t, bShape);
	else {
		PolyShape pShape;
		shape->MakePolyShape(t, pShape);
		bShape = pShape;	// UGH -- Convert it from a PolyShape -- not good!
		}
	
//DebugPrint(_T("Extrude organizing shape\n"));
	ShapeHierarchy hier;
	bShape.OrganizeCurves(t, &hier);
	// Need to flip the reversed polys...
	bShape.Reverse(hier.reverse);
	// ...and tell the hierarchy they're no longer reversed!
	hier.reverse.ClearAll();

	// Our shapes are now organized for patch-making -- Let's do the sides!
	int polys = bShape.splineCount;
	int poly, knot;
	int levelVerts = 0, levelVecs = 0, levelPatches = 0, nverts = 0, nvecs = 0, npatches = 0;
	int TVlevels = levels + 1, levelTVerts = 0, ntverts = 0, ntpatches = 0;
	BOOL anyClosed = FALSE;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		if(spline->Closed())
			anyClosed = TRUE;
		levelVerts += spline->KnotCount();
		levelTVerts += (spline->Segments() + 1);
		levelVecs += (spline->Segments() * 2);
		levelPatches += spline->Segments();
		}
	nverts = levelVerts * (levels + 1);
	npatches = levelPatches * levels;
	nvecs = (levelVecs * (levels + 1)) + levels * levelVerts * 2 + npatches * 4;
	if(texturing) {
		ntverts = levelTVerts * TVlevels;
		ntpatches = npatches;
		}

	pmesh.setNumVerts(nverts);
	pmesh.setNumVecs(nvecs);
	pmesh.setNumPatches(npatches);
	pmesh.setNumTVerts(ntverts);
	pmesh.setNumTVPatches(ntpatches);

	// Create the vertices!
	int vert = 0;
	int level;
	Point3 offset1, offset2;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int knots = spline->KnotCount();
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			if(level == 0)
				offset1 = offset;
			else
			if(level == levels)
				offset2 = offset;
			for(knot = 0; knot < knots; ++knot) {
				Point3 p = spline->GetKnotPoint(knot);
				pmesh.setVert(vert++, p + offset);
				}
			}
		}
	assert(vert == nverts);

    BOOL usePhysUVs = GetUsePhysicalScaleUVs();
	// Maybe create the texture vertices
	if(texturing) {
		int tvert = 0;
		int level;
		for(poly = 0; poly < polys; ++poly) {
			Spline3D *spline = bShape.splines[poly];
			if(!spline->KnotCount())
				continue;
			// Make it a polyline
			PolyLine pline;
			spline->MakePolyLine(pline, 10);
			int knots = spline->KnotCount();
			for(level = 0; level < TVlevels; ++level) {
				float tV = (float)level / (float)(TVlevels - 1);
                float vScale = usePhysUVs ? amount : 1.0f;
				int lverts = pline.numPts;
				int tp = 0;
				int texPts = spline->Segments() + 1;
				float cumLen = 0.0f;
				float totLen = pline.CurveLength();
                float uScale = usePhysUVs ? totLen : 1.0f;
				Point3 prevPt = pline.pts[0].p;
				int plix = 0;
				while(tp < texPts) {
					Point3 &pt = pline[plix].p;
					cumLen += Length(pt - prevPt);
					prevPt = pt;
					if(pline[plix].flags & POLYPT_KNOT) {
						float tU;
						if(tp == (texPts - 1))
							tU = 1.0f;
						else
							tU = cumLen / totLen;
						pmesh.setTVert(tvert++, UVVert(uScale*tU, vScale*tV, 0.0f));
						tp++;
						}
					plix = (plix + 1) % pline.numPts;
					}
				}
			}
		assert(tvert == ntverts);
		}

	// Create the vectors!
	int seg;
	int vec = 0;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int segs = spline->Segments();
		int knots = spline->KnotCount();
		// First, the vectors on each level
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			for(seg = 0; seg < segs; ++seg) {
				int seg2 = (seg + 1) % knots;
				if(spline->GetLineType(seg) == LTYPE_CURVE) {
					Point3 p = spline->GetOutVec(seg);
					pmesh.setVec(vec++, p + offset);
					p = spline->GetInVec(seg2);
					pmesh.setVec(vec++, p + offset);
					}
				else {
					Point3 p = spline->InterpBezier3D(seg, 0.333333f);
					pmesh.setVec(vec++, p + offset);
					p = spline->InterpBezier3D(seg, 0.666666f);
					pmesh.setVec(vec++, p + offset);
					}
				}
			}
		// Now, the vectors between the levels
		int baseVec = vec;
		for(level = 0; level < levels; ++level) {
			Point3 offsetA = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			Point3 offsetB = Point3(0.0f, 0.0f, baseZ + (float)(level + 1) / (float)levels * zSize);
			Point3 offset1 = offsetA + (offsetB - offsetA) * 0.333333333f;
			Point3 offset2 = offsetA + (offsetB - offsetA) * 0.666666666f;
			for(knot = 0; knot < knots; ++knot) {
				Point3 p = spline->GetKnotPoint(knot);
				pmesh.setVec(vec++, p + offset1);
				pmesh.setVec(vec++, p + offset2);
				}
			}
		}

	// Create the patches!
	int np = 0;
	int baseVert = 0;
	int baseVec = 0;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int knots = spline->KnotCount();
		int segs = spline->Segments();
		int baseVec1 = baseVec;	// Base vector index for this level
		int baseVec2 = baseVec + segs * 2 * (levels + 1);	// Base vector index for between levels
		for(level = 0; level < levels; ++level) {
			int sm = 0;
			BOOL firstSmooth = (spline->GetLineType(0) == LTYPE_CURVE && spline->GetLineType(segs-1) == LTYPE_CURVE && (spline->GetKnotType(0) == KTYPE_AUTO || spline->GetKnotType(0) == KTYPE_BEZIER)) ? TRUE : FALSE;
			for(seg = 0; seg < segs; ++seg, vec += 4) {
				int prevseg = (seg + segs - 1) % segs;
				int seg2 = (seg + 1) % knots;
				int a,b,c,d,ab,ba,bc,cb,cd,dc,da,ad;
				MtlID mtl = useShapeIDs ? spline->GetMatID(seg) : 2;
				a = baseVert + seg;
				b = baseVert + seg2;
				c = b + knots;
				d = a + knots;
				ab = baseVec1 + seg * 2;
				ba = ab + 1;
				bc = baseVec2 + seg2 * 2;
				cb = bc + 1;
				cd = ba + (segs * 2);
				dc = ab + (segs * 2);
				da = baseVec2 + seg * 2 + 1;
				ad = da - 1;
//DebugPrint(_T("Making patch %d: %d (%d %d) %d (%d %d) %d (%d %d) %d (%d %d)\n"),np, a, ab, ba, b, bc, cb, c, cd, dc, d, da, ad);
				// If the vertex is not smooth, go to the next group!
				if(seg > 0 && !(spline->GetLineType(prevseg) == LTYPE_CURVE && spline->GetLineType(seg) == LTYPE_CURVE && (spline->GetKnotType(seg) == KTYPE_AUTO || spline->GetKnotType(seg) == KTYPE_BEZIER))) {
					sm++;
					if(sm > 2)
						sm = 1;
					}
				DWORD smoothGroup = 1 << sm;
				if(seg == segs - 1 && firstSmooth) {
					smoothGroup |= 1;
					}
				pmesh.MakeQuadPatch(np, a, ab, ba, b, bc, cb, c, cd, dc, d, da, ad, vec, vec+1, vec+2, vec+3, smooth ? smoothGroup : 0);
				pmesh.setPatchMtlIndex(np++, genMatIDs ? mtl : 0);
				}
			baseVert += knots;
			baseVec1 += (segs * 2);
			baseVec2 += (knots * 2);
			}
		baseVert += knots;
		baseVec += (segs * 2 * (levels + 1) + knots * 2 * levels);
		}
	assert(vec == nvecs);
	assert(np == npatches);

 	// Maybe create the texture patches!
	if(texturing) {
		int ntp = 0;
		int baseTVert = 0;
		for(poly = 0; poly < polys; ++poly) {
			Spline3D *spline = bShape.splines[poly];
			if(!spline->KnotCount())
				continue;
			int pknots = spline->Segments() + 1;
			int pverts = pknots * TVlevels;
			int segs = spline->Segments();
			for(level = 0; level < levels; ++level) {
				for(seg = 0; seg < segs; ++seg) {
					int prevseg = (seg + segs - 1) % segs;
					int seg2 = seg + 1;
					int a,b,c,d;
					a = baseTVert + seg;
					b = baseTVert + seg2;
					c = b + pknots;
					d = a + pknots;
					TVPatch &tp = pmesh.getTVPatch(ntp++);
					tp.setTVerts(a, b, c, d);
					
					}
				baseTVert += pknots;
				}
			baseTVert += pknots;
			}
		assert(ntp == ntpatches);
		}

	// If capping, do it!
	if(anyClosed && (capStart || capEnd)) {
		PatchCapInfo capInfo;
		bShape.MakeCap(t, capInfo);

		// Build information for capping
		PatchCapper capper(bShape);
		if(capStart) {
			vert = 0;
			int baseVec = 0;
			for(poly = 0; poly < polys; ++poly) {
				Spline3D *spline = bShape.splines[poly];
				if(!spline->KnotCount())
					continue;
				PatchCapPoly &capline = capper[poly];
				int lverts = spline->KnotCount();
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				vert += lverts * levels;
				vec = baseVec;
				int lvecs = spline->Segments() * 2;
				for(int v = 0; v < lvecs; ++v)
					capline.SetVec(v, vec++);			// Gives this vec's location in the mesh!
				baseVec += lvecs * (levels + 1) + spline->KnotCount() * levels * 2;
				}
			// Create a work matrix for capping
			Matrix3 mat = TransMatrix(offset1);
			int oldPatches = pmesh.numPatches;
			capper.CapPatchMesh(pmesh, capInfo, TRUE, 16, &mat, genMatIDs ? -1 : 0);
			// If texturing, create the texture patches and vertices
			if(texturing)
				MakePatchCapTexture(pmesh, Inverse(mat), oldPatches, pmesh.numPatches, usePhysUVs);
			}
		if(capEnd) {
			int baseVert = 0;
			int baseVec = 0;
			for(poly = 0; poly < polys; ++poly) {
				Spline3D *spline = bShape.splines[poly];
				if(!spline->KnotCount())
					continue;
				PatchCapPoly &capline = capper[poly];
				int lverts = spline->KnotCount();
				int vert = baseVert + lverts * levels;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				baseVert += lverts * (levels + 1);
				int lvecs = spline->Segments()*2;
				int vec = baseVec + lvecs * levels;
				for(int v = 0; v < lvecs; ++v)
					capline.SetVec(v, vec++);			// Gives this vec's location in the mesh!
				baseVec += lvecs * (levels + 1) + spline->KnotCount() * levels * 2;
				}
			// Create a work matrix for grid capping
			Matrix3 mat = TransMatrix(offset2);
			int oldPatches = pmesh.numPatches;
			capper.CapPatchMesh(pmesh, capInfo, FALSE, 16, &mat, genMatIDs ? -1 : 0);
			// If texturing, create the texture patches and vertices
			if(texturing)
				MakePatchCapTexture(pmesh, Inverse(mat), oldPatches, pmesh.numPatches, usePhysUVs);
			}
		}

	//watje new mapping
	if(texturing)
		{
		if (ver < 4)
			{
			for (int i = 0; i < pmesh.numPatches; i++)
				pmesh.patches[i].flags |= PATCH_LINEARMAPPING;
			}
		}


	// Ready the patch representation!
	if( !pmesh.buildLinkages() )
   {
      assert(0);
   }
	pmesh.computeInteriors();
	}
Esempio n. 13
0
//***************************************************************************
// Calculate ambient or diffuse color at each vertex.
// Pass in TRUE as the "diffuse" parameter to calculate the diffuse color.
// If FALSE is passed in, ambient color is calculated.
//***************************************************************************
BOOL calcMixedVertexColors(INode* node, TimeValue t, int lightModel, ColorTab& vxColTab, EvalColProgressCallback* fn)
{
	ObjectState ostate;
	BOOL deleteTri;
	Mesh* mesh;
	SContext sc;
	DefaultLight dl1, dl2;
	MtlBaseLib mtls;
	Matrix3 tm;

	sc.SetNodeAndTime(node, t);
	tm = sc.tmAfterWSM;

	TriObject* tri = GetTriObjectFromNode(node, t, deleteTri);

	// We will only work on GeomObjects
	if (!tri) {
		return FALSE;
	}

	// Get the mesh from the object
	mesh = &tri->GetMesh();
	if (!mesh) {
		return FALSE;
	}

	// If the node doesn't have a material attached,
	// we create a dummy material.
	Mtl* mtl = node->GetMtl();
	if (!mtl) {
		mtl = new DumMtl(Color(node->GetWireColor()));
	}

	mesh->buildRenderNormals();

	vxColTab.ZeroCount();
	vxColTab.Shrink();

	sc.SetMesh(mesh);
	sc.CalcBoundObj();

	// Add the material to the list
	mtls.AddMtl(mtl);

	// Setup ambient light
	if (lightModel == LIGHT_AMBIENT) {
		sc.SetAmbientLight(Color(1.0f, 1.0f, 1.0f));
	}
	else {
		sc.SetAmbientLight(Color(0.0f, 0.0f, 0.0f));
	}

	// If we're using the real lights, we need to find them first
	if (lightModel == LIGHT_SCENELIGHT) {
		AddSceneLights(&sc, &mtls);

		// Add default lights if there are no lights in the scene
		if (sc.lightTab.Count() == 0) {
			dl1.ls.intens = 1.0f;
			dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl1.ls.type = OMNI_LGT;
			dl1.tm = TransMatrix(1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			dl2.ls.intens = 1.0f;
			dl2.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl2.ls.type = OMNI_LGT;
			dl2.tm = TransMatrix(-1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			sc.AddLight(new LightInfo(&dl1));
			sc.AddLight(new LightInfo(&dl2));
		}

		sc.SetAmbientLight(GetCOREInterface()->GetAmbient(t, FOREVER));
	}

	sc.UpdateLights();
	// Update material
	mtl->Update(t, FOREVER);
	
	int numVerts = mesh->numVerts;
	for (unsigned int v = 0; v < (unsigned)numVerts; v++) {

		if (fn) {
			if (fn->progress(float(v)/float(numVerts))) {
				if (deleteTri) {
					delete tri;
				}

				mtls.Empty();

				if (mtl->ClassID() == DUMMTL_CLASS_ID) {
					delete mtl;
				}

				// What to return here is up for discussion.
				// 1) We are aborting so FALSE might be in order.
				// 2) We have calculated some colors. Let's use what we've got so far.
				return TRUE;
			}
		}

		// Create a new entry
		Color* vxCol = new Color;
		Point3 tmpCol(0.0f, 0.0f, 0.0f);

		int numShades = 0;
		BitArray faceList;
		faceList.SetSize(mesh->numFaces, 0);

		// Get vertex normal
		// We also pass in a BitArray that will be filled in with
		// to inform us to which faces this vertex belongs.
		// We could do this manually, but we need to do it to get
		// the vertex normal anyway so this is done to speed things
		// up a bit.
		Point3 vxNormal = interpVertexNormal(mesh, tm, v, faceList);
		Point3 viewDir = -vxNormal;
		Point3 viewPoint = tm*mesh->verts[v] + 5.0f*vxNormal;
		Point3 lightPos = viewPoint;
		Point3 viewTarget = tm*mesh->verts[v];

		// We now have a viewpoint and a view target.
		// Now we just have to shade this point on the mesh in order
		// to get it's color.
		// Note: 
		// Since materials are assigned on Face basis we need to render each
		// vertex as many times as it has connecting faces.
		// the colors collected are mixed to get the resulting
		// color at each vertex.
		
		for (int nf = 0; nf < faceList.GetSize(); nf++) {
			if (faceList[nf]) {
				// render vertex for this face.
				sc.SetViewPoint(viewPoint);
				sc.SetTargetPoint(viewTarget);
				sc.SetViewDir(viewDir);
				sc.SetFaceNum(nf);
				Face* f = &mesh->faces[nf];
				sc.SetMtlNum(f->getMatID());
				sc.CalcNormals();

				// Setup the barycentric coordinate
				if (mesh->faces[nf].v[0] == v)
					sc.SetBaryCoord(Point3(1.0f, 0.0f, 0.0f));
				else if (mesh->faces[nf].v[1] == v)
					sc.SetBaryCoord(Point3(0.0f, 1.0f, 0.0f));
				else if (mesh->faces[nf].v[2] == v)
					sc.SetBaryCoord(Point3(0.0f, 0.0f, 1.0f));

				// Use diffuse color instead of ambient
				// The only difference is that we create a special light
				// located at the viewpoint and we set the ambient light to black.
				if (lightModel == LIGHT_DIFFUSE) {
					dl1.ls.intens = 1.0f;
					dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
					dl1.ls.type = OMNI_LGT;
					dl1.tm = TransMatrix(lightPos);

					sc.ClearLights();
					sc.AddLight(new LightInfo(&dl1));
					sc.UpdateLights();
				}


				// Shade the vertex
				mtl->Shade(sc);

				tmpCol.x += sc.out.c.r;
				tmpCol.y += sc.out.c.g;
				tmpCol.z += sc.out.c.b;
				numShades++;
			}
		}

		// The color mixes. We just add the colors together and 
		// then divide with as many colors as we added.
		if (numShades > 0) {
			tmpCol = tmpCol / (float)numShades;
		}

		
		vxCol->r = tmpCol.x;
		vxCol->g = tmpCol.y;
		vxCol->b = tmpCol.z;

		
		vxCol->ClampMinMax();

		
		// Append the Color to the table. If the array needs
		// to be realloc'ed, allocate extra space for 100 points.
		vxColTab.Append(1, &vxCol, 100);
	}

	// Some objects gives us a temporary mesh that we need to delete afterwards.
	if (deleteTri) {
		delete tri;
	}


	mtls.Empty();

	if (mtl->ClassID() == DUMMTL_CLASS_ID) {
		delete mtl;
	}

	return TRUE;
}
Esempio n. 14
0
FloatArray Quadr::ComputeStress()
{
	const double a = 1 + sqrt(3) / 2, b = -1.0 / 2, c = 1 - sqrt(3) / 2;
	FloatMatrix TransMatrix(4, 4);
	TransMatrix.at(0, 0) = a;
	TransMatrix.at(0, 1) = b;
	TransMatrix.at(0, 2) = c;
	TransMatrix.at(0, 3) = b;
	TransMatrix.at(1, 0) = b;
	TransMatrix.at(1, 1) = a;
	TransMatrix.at(1, 2) = b;
	TransMatrix.at(1, 3) = c;
	TransMatrix.at(2, 0) = c;
	TransMatrix.at(2, 1) = b;
	TransMatrix.at(2, 2) = a;
	TransMatrix.at(2, 3) = b;
	TransMatrix.at(3, 0) = b;
	TransMatrix.at(3, 1) = c;
	TransMatrix.at(3, 2) = b;
	TransMatrix.at(3, 3) = a;
	Strain.Clear();
	
	GaussPoint B;
	FloatArray Coor;
	FloatArray TransTemp(4);
	Coor.SetSize(2);

	Coor.at(0) = 0;
	Coor.at(1) = 0;
	B.Init(0, Coor);
	ComputeJacobi(B);
	BMatrixBig = ComputeBMatrix();
	//BMatrixBig.Print();
	//Displacement.Print();
	Strain = BMatrixBig.Mult(Displacement);
	Stress = DMatrix.Mult(Strain);

	for (int inode = 0; inode < 4; inode++)
	{
		Coor.at(0) = P4ksicor[inode];
		Coor.at(1) = P4etacor[inode];
		B.Init(0, Coor);
		ComputeJacobi(B);
		BMatrixBig = ComputeBMatrix();
		GaussStrain[inode] = BMatrixBig.Mult(Displacement);
		GaussStress[inode] = DMatrix.Mult(Strain);
		//GaussStrain[inode].Print();
	}
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			TransTemp.at(j) = GaussStrain[j].at(i);
		}
		TransTemp = TransMatrix.Mult(TransTemp);
		for (int j = 0; j < 4; j++)
		{
			NodeStrain[j].at(i) = TransTemp.at(j);
		}
		for (int j = 0; j < 4; j++)
		{
			TransTemp.at(j) = GaussStress[j].at(i);
		}
		TransTemp = TransMatrix.Mult(TransTemp);
		for (int j = 0; j < 4; j++)
		{
			NodeStress[j].at(i) = TransTemp.at(j);
		}
	}
	return NULL;
}