Beispiel #1
0
void Mesh::surfRev(int numSlices, Vector3 linePoints[], int numPoints)
{
	float angleBetween = ToRadian(360 / numSlices);
	Matrix rotate;
	Identity(&rotate);
	RotateY(&rotate,angleBetween);
	Vector3* originalPoints = linePoints;
	//arrays of the points for the caps if they are necessary
	//in the event the shap has a hole in one of the ends
	Vector3* topCap = new Vector3[numSlices];
	Vector3* bottomCap = new Vector3[numSlices];

	for(int i = 0; i < numSlices; i++)
	{
		topCap[i] = originalPoints[numPoints-1];
		bottomCap[i] = originalPoints[0];
		Vector3* newPoints = new Vector3[numPoints];
		for(int k = 0; k < numPoints; k++)
		{
			Vector4 point = Vector4(originalPoints[k].x,originalPoints[k].y,originalPoints[k].z,1);
			D3DXVec3Transform(&point,&originalPoints[k],&rotate);
			newPoints[k] = Vector3(point.x,point.y,point.z);
		}
		for(int j = 0; j < numPoints; j++)
		{
			Vector3* side = new Vector3[4];
			side[0] = originalPoints[j];
			if((j+1)<numPoints)
			{
				side[1] = originalPoints[j+1];
				side[2] = newPoints[j+1];
			}
			else
			{
				side[1] = originalPoints[0];
				side[2] = newPoints[0];
			}
			side[3] = newPoints[j];
			makePolygon(side,4,j);
			//set the texture coordinates
			vertices[vertices.size()-4].texC = Vector2((i*numSlices*(1/360)),0);
			vertices[vertices.size()-3].texC = Vector2((i*numSlices*2*(1/360)),0);
			vertices[vertices.size()-2].texC = Vector2((i*numSlices*2*(1/260)),1);
			vertices[vertices.size()-1].texC = Vector2((i*numSlices*(1/360)),1);
		}
		originalPoints = newPoints;
		//delete[] newPoints;
	}

	//add end cap if necessary
	if(linePoints[numPoints-1].x!=0)
	{
		makePolygon(topCap,numSlices,0);
	}
	if(linePoints[0].x!=0)
	{
		makePolygon(bottomCap,numSlices,0);
	}
	delete[] topCap;
}
Beispiel #2
0
/*
 * Called when the user clicked (or released) a mouse buttons inside the window.
 */
void mouse_clicked(int button, int state, int x, int y) {
	// guard against both left and right buttons being pressed at the same time,
	// by only responding when a mouse button is pressed while another one
	// hasn't been pressed yet
	if (state == GLUT_DOWN && mouse_mode == 0) {
		if (button == GLUT_LEFT_BUTTON) {
			mouse_mode = GLUT_LEFT_BUTTON;
			num_vertices++;

			/* Convert clicked mouse point to world vertex. */
			draw_vertices[num_vertices].x = x * (world_x / reso_x);
			draw_vertices[num_vertices].y = (reso_y - y) * (world_y / reso_y);

			if (num_vertices > 0) {
				float distance = calcDistance(draw_vertices[num_vertices].x, draw_vertices[num_vertices].y,
					draw_vertices[num_vertices - 1].x, draw_vertices[num_vertices - 1].y);
				if (distance < 0.01) {
					num_vertices--;
				}
			}

			if (num_vertices == max_vertices - 1) {
				makePolygon(1, 0, 0, draw_vertices, num_vertices + 1, num_created_bodies++);
			}

			// printf("num_vertices = %d, max_vertices = %d\n", num_vertices, max_vertices);
		} else if (button == GLUT_RIGHT_BUTTON) {
			mouse_mode = GLUT_RIGHT_BUTTON;
			if (num_vertices > 1) {
				makePolygon(1, 0, 0, draw_vertices, num_vertices + 1, num_created_bodies++);
			}

			/* Possible TODO: Remove the point? */
		}
	} else if (state == GLUT_UP && button == mouse_mode) {
		// pressed button released
		mouse_mode = 0;
	}
}
Beispiel #3
0
/*
 * Load a given world, i.e. read the world from the `levels' data structure and
 * convert it into a Box2D world.
 */
void load_world(unsigned int level) {
	// Pause the game when loading a new level
	play = 0;

	if (level >= num_levels) {
		// Note that level is unsigned but we still use %d so -1 is shown as
		// such.
		printf("Warning: level %d does not exist.\n", level);
		return;
	}

	// Create a Box2D world and populate it with all bodies for this level
	// (including the ball).
	current_level = level + 1;
	cur_level = &(levels[level]);
	init(cur_level->num_joints);
	b2Vec2 gravity (0, -9.81);
	bool do_sleep = true;

	world = new b2World(gravity);
	world->SetAllowSleeping(do_sleep);

	// printf("num_polygons = %i\n", levels[0].num_polygons);
	// printf("is_Dynamic = %d\n", levels[0].polygons[0].is_dynamic);

	// Create ground
	b2BodyDef groundBodyDef;
	groundBodyDef.position.Set(0.0f, -world_y / 2);
	ground = world->CreateBody(&groundBodyDef);

	// addBodyToCreatedBodies(ground, num_created_bodies++);

	b2PolygonShape groundBox;
	groundBox.SetAsBox(world_x, world_y / 2);
	ground->CreateFixture(&groundBox, 0.0f);

	// Setup rest of level.
	for (unsigned int i = 0; i < cur_level->num_polygons; i++) {
		b2Vec2 *vertices = new b2Vec2[cur_level->polygons[i].num_verts];

		for (unsigned int j = 0; j < cur_level->polygons[i].num_verts; j ++) {
			vertices[j].Set(cur_level->polygons[i].verts[j].x, cur_level->polygons[i].verts[j].y);
		}

		makePolygon(cur_level->polygons[i].is_dynamic, cur_level->polygons[i].position.x,
			cur_level->polygons[i].position.y, vertices, cur_level->polygons[i].num_verts,
			num_created_bodies++);

		delete[] vertices;
	}

	// Create ball
	b2BodyDef ballBodyDef;
	ballBodyDef.type = b2_dynamicBody;
	ballBodyDef.position.Set(cur_level->start.x, cur_level->start.y);
	ball = world->CreateBody(&ballBodyDef);

	b2CircleShape dynamicCircle;
	dynamicCircle.m_radius = ball_radius;

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dynamicCircle;
	fixtureDef.density = 1.0f;
	fixtureDef.friction = 0.3f;
	ball->CreateFixture(&fixtureDef);

	// Setup joints.
	for (unsigned int i = 0; i < cur_level->num_joints; i++) {
		if (cur_level->joints[i].joint_type == JOINT_REVOLUTE) {
			b2RevoluteJointDef jointDef;
			// jointDef.anchorPoint = objectA->GetPosition();
			b2Body *objectA = created_bodies[cur_level->joints[i].objectA];
			b2Body *objectB = created_bodies[cur_level->joints[i].objectB];

			b2Vec2 anchorPoint(cur_level->joints[i].anchor.x,
				cur_level->joints[i].anchor.y);
			jointDef.Initialize(objectA, objectB, anchorPoint);

			world->CreateJoint(&jointDef);
		}

		else if (cur_level->joints[i].joint_type == JOINT_PULLEY) {
			b2Vec2 anchorPoint1(cur_level->joints[i].anchor.x, cur_level->joints[i].anchor.x);
			b2Vec2 anchorPoint2(cur_level->joints[i].pulley.anchor2.x, cur_level->joints[i].pulley.anchor2.x);
			b2Vec2 groundAnchor1(cur_level->joints[i].pulley.ground1.x, cur_level->joints[i].pulley.ground1.y);
			b2Vec2 groundAnchor2(cur_level->joints[i].pulley.ground2.x, cur_level->joints[i].pulley.ground2.y);
			float ratio = cur_level->joints[i].pulley.ratio;

			b2Body *objectA = created_bodies[cur_level->joints[i].objectA];
			b2Body *objectB = created_bodies[cur_level->joints[i].objectB];

			b2PulleyJointDef jointDef;
			jointDef.Initialize(objectA, objectB, groundAnchor1, groundAnchor2, anchorPoint1, anchorPoint2, ratio);
			world->CreateJoint(&jointDef);
		}
	}
}
Beispiel #4
0
int main()
{
    int pmap[NUMTHREAD][WIDTH][HEIGHT];
    //fill all member = -1
    memset(pmap, -1, sizeof(pmap) );

    // polygons
    std::vector<polygon> polygons;
    std::vector<value> values;

    for (int i = 0; i < NUMPOLYGON; i++)
    {
        polygon p = makePolygon(WIDTH, HEIGHT);
        bg::correct(p);
        polygons.push_back(p);
    }

    //std::cout<<polygons.size()<<std::endl;

    // display polygons
    // std::cout << "generated polygons:" << std::endl;
    // BOOST_FOREACH(polygon const & p, polygons)
    // std::cout << bg::wkt<polygon>(p) << std::endl;

    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();

    // fill the spatial index
    for ( int i = 0 ; i < polygons.size() ; ++i )
    {
        // calculate polygon bounding box
        box b = bg::return_envelope<box>(polygons[i]);
        // insert new value
        values.push_back(std::make_pair(b, i));
    }

    RTREE rtree(values.begin(), values.end());

    std::thread threads[NUMTHREAD];

    for (int i = 0; i < NUMTHREAD; i++)
    {
        threads[i] = std::thread([i, &rtree, &polygons, &pmap]() {
            DrawPolygon2(i, rtree, polygons, pmap[i]);
        });
    }

    for (int i = 0; i < NUMTHREAD; i++)
    {
        threads[i].join();
    }

    //concatenate
    int mapresult[WIDTH][HEIGHT];
    memset(mapresult,-1,sizeof(mapresult));

    for (int index = NUMTHREAD - 1; index >= 0; index--)
    {
        int xmin, ymin, xmax, ymax;
        box b;
        findCorner(xmin, ymin, xmax, ymax, b, index);
        for (int i = xmin; i < xmax; i++)
        {
            for (int j = ymin; j < ymax; j++)
            {
                int id = pmap[index][i][j];
                if (id != -1)
                {
                    mapresult[i][j] = id;
                }
            }
        }
    }

    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
    float duration = (float)(std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count()) / 1000;
    std::cout << "duration : " << duration << std::endl;


    //random color
    std::vector<int> colors;
    int size = polygons.size();
    for ( int i = 0 ; i < size ; ++i )
    {
        colors.push_back(i % 3 + 1);
    }

    //Draw pixel
    // t1 = std::chrono::high_resolution_clock::now();
    cv::Mat mat(HEIGHT, WIDTH, CV_8UC4);
    mat = cv::Scalar(0, 0, 0, 0);


    for (int i = 0; i < WIDTH; i++)
        for (int j = 0; j < HEIGHT; j++)
        {
            if (mapresult[i][j] != -1) {            
                int c = colors[mapresult[i][j]];
                auto color = c == 1 ? RED : c == 2 ? GREEN : BLUE;
                line( mat, cv::Point(i, j), cv::Point(i, j), color, 2, 8);
            }
        }

    line(mat, cv::Point(10, 10), cv::Point(251, 240), cv::Scalar(0, 0, 0, 255), 1, 8);


    std::vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);

    imwrite("DrawPolygon7.png", mat, compression_params);

    return 0;
}
Beispiel #5
0
int main()
{
    int pmap[WIDTH][HEIGHT];
    //fill all member = -1
    memset(pmap, -1, sizeof(pmap) );

    // polygons
    std::vector<polygon> polygons;
    std::vector<value> values;

    // create some polygons
    for ( unsigned i = 0 ; i < 10 ; ++i )
    {
        // create a polygon
        polygon p;
        for ( float a = 0 ; a < 6.28316f ; a += 1.04720f )
        {
            int x = 30 * i + int(20 *::cos(a));
            int y = 30 * i + int(20 *::sin(a));
            p.outer().push_back(point(x, y));
        }
        // add polygon
        polygons.push_back(p);
    }

    for(int i=0;i<100;i++)
    {
        polygon p = makePolygon(WIDTH,HEIGHT);
        polygons.push_back(p);
    }

    // display polygons
    std::cout << "generated polygons:" << std::endl;
    BOOST_FOREACH(polygon const & p, polygons)
    std::cout << bg::wkt<polygon>(p) << std::endl;

    // fill the spatial index
    for ( unsigned i = 0 ; i < polygons.size() ; ++i )
    {
        // calculate polygon bounding box
        box b = bg::return_envelope<box>(polygons[i]);
        // insert new value
        values.push_back(std::make_pair(b, i));
    }

    RTREE rtree(values.begin(), values.end());

    for (int i = 0; i < WIDTH; i++)
        for (int j = 0; j < HEIGHT; j++)
        {
            if (pmap[i][j] == -1)
            {
                std::vector<value> returned_values;

                point sought = point(i, j);

                for ( RTREE::const_query_iterator it = rtree.qbegin(bgi::nearest(sought, 1) ) ; it != rtree.qend() ; ++it )
                {
                    if (!bg::within(sought, polygons[it->second]))
                    {
                        break;
                    }
                    returned_values.push_back(*it);
                }

                if (returned_values.size() > 0)
                {
                    int count = 0;
                    int id = returned_values[0].second;
                    pmap[i][j] = id;
                    point pmin = returned_values[0].first.min_corner();
                    point pmax = returned_values[0].first.max_corner();

                    std::cout<<pmin.get<0>()<<", "<<pmin.get<1>()<<"    "<<pmax.get<0>()<<", "<<pmax.get<1>()
                    <<std::endl;

                    // for (int w = pmin.get<0>(); w < pmax.get<0>(); w++)
                    //     for (int h = pmin.get<1>(); h < pmax.get<1>(); h++)
                    //     {
                    //         if (w >= WIDTH || h >= HEIGHT)
                    //             continue;
                    //         if (bg::within(point(w, h), polygons[id]) != 0)
                    //         {
                    //             pmap[w][h] = id;
                    //         }
                    //     }                    

                    for (int w = 0; w < WIDTH; w++)
                        for (int h = 0; h < HEIGHT; h++)
                        {
                            if (w >= WIDTH || h >= HEIGHT)
                                continue;
                            if (bg::within(point(w, h), polygons[id]) != 0)
                            {
                                pmap[w][h] = id;
                            }
                        }
                }
            }
        }
            

    //random mau
    std::vector<int> colors;
    for ( unsigned i = 0 ; i < polygons.size() ; ++i )
    {
        colors.push_back(i % 3 + 1);
    }

    //DrawHinh

    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();    
    cv::Mat mat(HEIGHT, WIDTH, CV_8UC4);
    mat = cv::Scalar(0, 0, 0, 0);


    for (int i = 0; i < WIDTH; i++)
        for (int j = 0; j < HEIGHT; j++)
        {
            if (pmap[i][j] != -1) {
                int c = colors[pmap[i][j]];
                auto color = c == 1 ? RED : c == 2 ? GREEN : BLUE;
                line( mat, cv::Point(i, j), cv::Point(i, j), color ,  1, 8 );
            }
        }

    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
    float duration = (float)(std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count()) / 1000;
    std::cout << "duration DrawPolygon: " << duration << std::endl;

    std::vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);


    imwrite("DrawPolygon2.png", mat, compression_params);


    // find 5 nearest values to a point
    std::vector<value> result_n;
    rtree.query(bgi::nearest(point(0, 0), 1), std::back_inserter(result_n));

    // note: in Boost.Geometry the WKT representation of a box is polygon

    // note: the values store the bounding boxes of polygons
    // the polygons aren't used for querying but are printed


    std::cout << "knn query point:" << std::endl;
    std::cout << bg::wkt<point>(point(0, 0)) << std::endl;
    std::cout << "knn query result:" << std::endl;
    BOOST_FOREACH(value const & v, result_n)
    std::cout << bg::wkt<polygon>(polygons[v.second]) << std::endl;

    return 0;
}
int main (int argc, char **argv)
{

    // GLUT init

    osgInit(argc, argv);
    osgLog().setLogLevel ( OSG::LOG_DEBUG );

    FieldContainerPtr pProto = Geometry::getClassType().getPrototype();

    GeometryPtr pGeoProto = GeometryPtr::dcast(pProto);

    if(pGeoProto != NullFC)
    {
        pGeoProto->setDlistCache(true);
    }

    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    UInt32 id = glutCreateWindow("OpenSG");
    glutKeyboardFunc(key);
    glutReshapeFunc(resize);
    glutDisplayFunc(display);       
    // glutMouseFunc(mouse);   
    // glutMotionFunc(motion); 
    
    glutIdleFunc(display);
    
    // create a material (need that to test textures)
    
    ChunkMaterialPtr mat;  

    beginEditCP(mat);
    
    mat = ChunkMaterial::create();
   
    MaterialChunkPtr mc = MaterialChunk::create();  
 
    beginEditCP(mc);
    mc->setDiffuse( Color4f( 1,.8,.8,1 ) );
    mc->setAmbient( Color4f( 0.1,0.1,0.1,1 ) );
    mc->setSpecular( Color4f( 1,1,1,1 ) );
    mc->setShininess( 20 );
 
    mc->setBackMaterial(true);
    mc->setBackColorMaterial(GL_DIFFUSE);
    mc->setBackDiffuse( Color4f( 1,0,0,1 ) );
    mc->setBackAmbient( Color4f( 0.1,0.1,0.1,1 ) );
    mc->setBackSpecular( Color4f( 0,1,0,1 ) );
    mc->setBackShininess( 10 );
    mc->setLit(true);
 
    endEditCP(mc);

    mat->addChunk(mc);

    // Texture chunk
    
    UChar8 imgdata[] = 
        {  255,0,0,128,  0,255,0,128,  0,0,255,255,  255,255,255,255 };
    ImagePtr pImage = Image::create();
    pImage->set( Image::OSG_RGBA_PF, 2, 2, 1, 1, 1, 0, imgdata );

    if ( argc > 1 )
        pImage->read( argv[1] );
    
    TextureChunkPtr xchunk;
    xchunk = TextureChunk::create();
    xchunk->setImage( pImage );
    xchunk->setMinFilter( GL_NEAREST );
    xchunk->setMagFilter( GL_NEAREST );
    xchunk->setWrapS( GL_REPEAT );
    xchunk->setWrapT( GL_REPEAT );
    xchunk->setEnvMode( GL_MODULATE );

    mat->addChunk( xchunk );

    endEditCP(mat);

    objects[0] = makePolygon(ccwSquare, 
                             sizeof(ccwSquare)/sizeof(double[3]));
    objects[1] = makePolygon(ccwSquare, 
                             sizeof(ccwSquare)/sizeof(double[3]));
    
    objects[2] = makePolygon(star,
                             sizeof(star)/sizeof(double[3]));
    objects[3] = makePolygon(star,
                             sizeof(star)/sizeof(double[3]));
    
    objects[4] = makePolygon(cwSquare, 
                             sizeof(cwSquare)/sizeof(double[3]));
    objects[5] = makePolygon(cwSquare, 
                             sizeof(cwSquare)/sizeof(double[3]));
    
    objects[6] = makePolygon(doubleEight, 
                             sizeof(doubleEight)/sizeof(double[3]));
    objects[7] = makePolygon(doubleEight, 
                             sizeof(doubleEight)/sizeof(double[3]));

    //tesselate every second object
    for(int i = 1; i < nobjects; i+=2) {

      GeometryPtr::dcast(objects[i]->getCore())->setMaterial( mat );
      std::cerr << "Polygon Node: " << std::hex << objects[i] << std::endl;

      // try to create convex primitives
      OSG::GeometryPtr pGeo = GeometryPtr::dcast(objects[i]->getCore());

      std::cerr << "Tesselating polygon : "
                << i
                << std::endl;

      createConvexPrimitives(pGeo);
    }

    // normal material
    SimpleMaterialPtr nmat;     
    
    nmat = SimpleMaterial::create();
    beginEditCP(nmat);
    nmat->setEmission( Color3f( 0,1,0 ) );
    endEditCP(nmat);
    
    for ( UInt16 i = 0; i < nobjects; i++ )
    {
        normalobjects[i] = calcVertexNormalsGeo(
            GeometryPtr::dcast(objects[i]->getCore()), .5);

        GeometryPtr::dcast(normalobjects[i]->getCore())->setMaterial(nmat);
    }
    
    // 
    // The action

    win = GLUTWindow::create();
    win->setId(id);
    win->init();

    glEnable( GL_LIGHT0 );
    float p[4]={0,0,1,0};
    glLightfv(GL_LIGHT0, GL_POSITION, p);
    float c[4]={1,1,1,1};
    glLightfv(GL_LIGHT0, GL_DIFFUSE, c);
    glLightfv(GL_LIGHT0, GL_SPECULAR, c);
    
    glPointSize( 3 );
    
    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glClearColor( .3, .3, .8, 1 );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60, 1, 0.1, 10 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    gluLookAt( 3, 3, 3,  0, 0, 0,   0, 0, 1 );
   
    dact = DrawAction::create();
    dact->setWindow(get_pointer(win));
    dact->setFrustumCulling( false );

    glutMainLoop();
    
    return 0;
}
Beispiel #7
0
void Esh3DRenderer::render(const EshShape& in_shape, EshRendererContext& in_rendererContext,MfGdiBrush *in_brush)
{
    ChLOG_DEBUG_START_FN;
    if (!setUp(in_shape, in_rendererContext))
    {
        return;
    }

    // temporary pen & brush so I can see what I'm doing!
    //ChAutoPtr<MfGdiBrush> pBrush = m_driver.CreateSolidBrush(CsColour(0x88, 0x88, 0x88));
    //ChAutoPtr<MfGdiPen> pPen = m_driver.CreatePen(MfGdiPen::Style_Solid, 4, CsColour(0,0,0), ChVector<ChFLT8>());
    //ChAutoPtr<MfGdiBrush> pBrush = EshGdiObjectFactory::makeNullBrush(m_driver);
    ChAutoPtr<MfGdiPen> pPen(EshGdiObjectFactory::makeNullPen(m_driver)); // LINUX_PORT
    // TODO - pen must be null pen, but because faces aren't being shaded according to normal angle, an
    //        outline is being drawn to figure out where the faces are
    //in_rendererContext.getDeviceContextReference().SetBrush(*pBrush);
    //in_rendererContext.getDeviceContextReference().TakeBrush(pBrush.giveUpOwnership());
    in_rendererContext.getDeviceContextReference().TakePen(pPen.giveUpOwnership());

    if (in_rendererContext.hasTransformation())
    {
        // 2D rotation must be done before any 3D rotation/skew, so multiply on right of current
        // 3D world transform, which at this point will have the skew and rotation already
        m_worldTransform = m_worldTransform * CsMatrix3D<ChFLT8>(in_rendererContext.getTransformationMatrix());
    }

    m_pPathData = ChNEW EshPathRendererData(*m_pGeometry, in_rendererContext);
    m_pPathData->init();
    MfGdiDeviceContext& deviceContext = in_rendererContext.getDeviceContextReference();

    // use non-const verion of method to have geometry add implied segments
    const EshPathCommandTable& pathCommands = m_pPathData->getPathCommandsReference();
    if (pathCommands.size() == 0)
    {
        return;
    }

	bool skip				 = true;
    bool isFirstSegmentDrawn = false;

    CsPoint<ChFLT8> startPosition(0,0);
    CsPoint<ChFLT8> position(0,0);
    CsPoint<ChFLT8> nextPosition(0,0);

    const EshPathCommand* pCurrentPathCommand;
    const EshPathCommand* pNextPathCommand;

    ChUINT2 j = 0;

    /**
     * TODO - is it possible for the first path param to be an editing command?
     */
    pNextPathCommand = &pathCommands[0];
    EshPathCommandTypeEnums nextPathCommandType = pNextPathCommand->m_type;

    CsPlanarPolygon<ChFLT8> frontFace;
    CsPlanarPolygon<ChFLT8> extrusion;

    for (ChUINT4 i=1; i <= pathCommands.size(); i++)
    {
        pCurrentPathCommand = pNextPathCommand;

        // Skip editing commands
		skip = true;
        while ( skip && i < pathCommands.size())
        {
			skip = (ESH_PATH_CMD_HA <= pathCommands[i].m_type && pathCommands[i].m_type <= ESH_PATH_CMD_HI);
			if(skip)
			{
				++i;
			}
		}     
        
        if (i == pathCommands.size())
        {
            nextPathCommandType = ESH_PATH_CMD_E;
        }
        else
        {
            pNextPathCommand = &pathCommands[i];
            nextPathCommandType = pNextPathCommand->m_type;
        }

        bool isLastCommand = (nextPathCommandType == ESH_PATH_CMD_E);
        bool isEnd = isLastCommand;
        
        switch (pCurrentPathCommand->m_type)
        {
        case ESH_PATH_CMD_L:
            // Line to
//            openClosedPath(deviceContext);
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                m_pPathData->getPoint(nextPosition);
                //m_pPathData->getPoint(nextPosition);
                if (!isFirstSegmentDrawn)
                {
                    startPosition = position;
                    frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth));
                    isFirstSegmentDrawn = true;
                }

                if (m_isFilled)
                {
                    frontFace.addPoint(m_worldTransform * ChPoint3DF8(nextPosition, m_lForeDepth));
                }
                // TODO - linecap stuff

                makePolygon(position, nextPosition, extrusion);
                m_tree.insert(extrusion);
                position = nextPosition;
            }
            break;

        case ESH_PATH_CMD_C:
            // Cubic curve
//            openClosedPath(deviceContext);
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                ChPoint3DF8 p0(position.getX(), position.getY(), m_lForeDepth);
                ChPoint3DF8 p1(m_pPathData->getPointF8(), m_lForeDepth);  // 1st control point
                ChPoint3DF8 p2(m_pPathData->getPointF8(), m_lForeDepth);  // 2nd control point
                m_pPathData->getPoint(nextPosition);
                ChPoint3DF8 p3(nextPosition, m_lForeDepth);  // endpoint
                if (!isFirstSegmentDrawn)
                {
                    startPosition = position;
                    if (m_isFilled)
                    {
                        frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth));
                    }
                    isFirstSegmentDrawn = true;
                }

                divideBezier(p0, p1, p2, p3, frontFace);
                position = nextPosition;
            }
            break;

        case ESH_PATH_CMD_M:
            // Move to - count is always 1
            ChASSERT(pCurrentPathCommand->m_unCount == 1);
            m_pPathData->getPoint(position);
            break;
        case ESH_PATH_CMD_X:
            // Close path
            nextPosition = startPosition;
            if (position != nextPosition)
            {
                makePolygon(position, nextPosition, extrusion);
                m_tree.insert(extrusion);
                position = nextPosition;
            }
            
           if (m_isFilled)
            {
                m_faces.push_back(frontFace);
                frontFace.clear();
            }
            isFirstSegmentDrawn = false;
            break;
        case ESH_PATH_CMD_E:
            // End path data attribute
            /* Freeform paths will not have a close path command, however, if
               the path is filled, we still need a polygon for that line segment. */
            if (m_isFilled && position != startPosition)
            {
                makePolygon(position, startPosition, extrusion);
                m_tree.insert(extrusion);
                position = startPosition;
                m_faces.push_back(frontFace);
                frontFace.clear();
            }
            break;
       
        case ESH_PATH_CMD_AE:
            // Angle ellipse to
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition =  makeAngleEllipse(in_rendererContext, position, false, j, frontFace);
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeAngleEllipse(in_rendererContext, position, false, j, frontFace);
                }
            }
            break;

        case ESH_PATH_CMD_AL:
            // Angle ellipse
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition =  makeAngleEllipse(in_rendererContext, position, true, j, frontFace);
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeAngleEllipse(in_rendererContext, position, true, j, frontFace);
                }
            }
            break;

        case ESH_PATH_CMD_AT:
            // Arc to
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition = makeArc(position, false, j, false, frontFace);
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeArc(position, false, j, false, frontFace);
                }

                
            }
            break;

        case ESH_PATH_CMD_AR:
            // Arc
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition = makeArc(position, true, j, false, frontFace);
                    frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth));
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeArc(position, true, j, false, frontFace);
                }
            }
            break;

        case ESH_PATH_CMD_WA:
            // Clockwise arc to
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition = makeArc(position, false, j, true, frontFace);
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeArc(position, false, j, true, frontFace);
                }
            }
            break;

        case ESH_PATH_CMD_WR:
            // Clockwise arc
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                if (!isFirstSegmentDrawn)
                {
                    startPosition = makeArc(position, true, j, true, frontFace);
                    frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth));
                    isFirstSegmentDrawn = true;
                }
                else
                {
                    makeArc(position, true, j, true, frontFace);
                }               
            }
            break;

        case ESH_PATH_CMD_QX:
            // Elliptical quadrant x
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                if (!isFirstSegmentDrawn)
                {
                    startPosition = position;
                    isFirstSegmentDrawn = true;
                }
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                makeQuadrantArc(position, j % 2 == 0, frontFace);

            }
            break;

        case ESH_PATH_CMD_QY:
            // Elliptical quadrant y
            for (j=0; j < pCurrentPathCommand->m_unCount; j++)
            {
                if (!isFirstSegmentDrawn)
                {
                    startPosition = position;
                    frontFace.addPoint(m_worldTransform * ChPoint3DF8(position, m_lForeDepth));
                    isFirstSegmentDrawn = true;
                }
                isEnd = isLastCommand && (j == pCurrentPathCommand->m_unCount - 1);
                makeQuadrantArc(position, j % 2 == 1, frontFace);
            }
            break;
        }

    }

    // Draw the actual shape.
    m_tree.render(m_driver, in_rendererContext);
    if (m_isFilled)
    {
        ChBYTE opacity = 255;
        const EshFill &fill = in_shape.getFill();

        if (fill.isOpacitySet())
        {
            opacity = fill.getOpacity() >> 8;
        }

        renderPrimaryFaces(deviceContext,in_brush,opacity);
    }
Beispiel #8
0
int main(int argc, char** argv)
{
    bool timeit = FALSE;
    QApplication app(argc,argv);

    bool scrollbars=FALSE;

    for (int arg=1; arg<argc; arg++) {
	if (0==strcmp(argv[arg],"-bounce")) {
	    bouncers=atoi(argv[++arg]);
	} else if (0==strcmp(argv[arg],"-help") ||
		   0==strcmp(argv[arg],"--help")) {
	    showtext=FALSE;
	} else if (0==strcmp(argv[arg],"-redraws")) {
	    showredraws=TRUE;
	} else if (0==strcmp(argv[arg],"-lines")) {
	    showlines=TRUE;
	} else if (0==strcmp(argv[arg],"-btext")) {
	    btext=FALSE;
	} else if (0==strcmp(argv[arg],"-dsprite")) {
	    dsprite=FALSE;
	} else if (0==strcmp(argv[arg],"-dpoly")) {
	    dpoly=!dpoly;
	} else if (0==strcmp(argv[arg],"-delay")) {
	    refresh_delay=atoi(argv[++arg]);
	} else if (0==strcmp(argv[arg],"-sb")) {
	    scrollbars=TRUE;
	} else if (0==strcmp(argv[arg],"-noopt")) {
	    QPixmap::setDefaultOptimization( QPixmap::NoOptim );
	} else if (0==strcmp(argv[arg],"-bestopt")) {
	    QPixmap::setDefaultOptimization( QPixmap::BestOptim );
#ifdef _WS_WIN_
	} else if (0==strcmp(argv[arg],"-bsm")) {
	    extern bool qt_bitblt_bsm;
	    qt_bitblt_bsm=TRUE;
#endif
	} else if (0==strcmp(argv[arg],"-iter")) {
	    iterations=atoi(argv[++arg]);
	    timeit = TRUE;
	} else {
	    warning("Bad param %s", argv[arg]);
	}
    }

    QMainWindow m;
    MySpriteField field(IMG_BACKGROUND,scrollbars ? WIDTH*3 : WIDTH,
		scrollbars ? HEIGHT*3 : HEIGHT);
    Example example(scrollbars,field,&m);

    QMenuBar* menu = m.menuBar();

    QPopupMenu* file = new QPopupMenu;
    file->insertItem("New view", &example, SLOT(makeSlave()), CTRL+Key_N);
    file->insertSeparator();
    file->insertItem("Quit", qApp, SLOT(quit()), CTRL+Key_Q);
    menu->insertItem("&File", file);

    QPopupMenu* edit = new QPopupMenu;
    edit->insertItem("New polygon", &example, SLOT(makePolygon()));
    edit->insertItem("New ellipse", &example, SLOT(makeEllipse()));
    edit->insertItem("New rectangle", &example, SLOT(makeRectangle()));
    menu->insertItem("&Edit", edit);

    MyPopupMenu* options = new MyPopupMenu;
    options->insertCheckItem("Show help text", &showtext, CTRL+Key_H);
    options->insertCheckItem("Show bouncing text", &btext, CTRL+Key_T);
    options->insertCheckItem("Show polygon", &dpoly, CTRL+Key_P);
    options->insertCheckItem("Show drawn sprite", &dsprite, CTRL+Key_D);
    options->insertCheckItem("Show redraw areas", &showredraws, CTRL+Key_A);
    options->insertCheckItem("Show foreground lines", &showlines, CTRL+Key_L);
    options->insertSeparator();
    options->insertRadioItem("1 bouncer", &bouncers, 1);
    options->insertRadioItem("3 bouncers", &bouncers, 3);
    options->insertRadioItem("10 bouncers", &bouncers, 10);
    options->insertRadioItem("30 bouncers", &bouncers, 30);
    options->insertRadioItem("100 bouncers", &bouncers, 100);
    options->insertRadioItem("1000 bouncers", &bouncers, 1000);
    options->insertSeparator();
    options->insertRadioItem("No delay", &refresh_delay, 0);
    options->insertRadioItem("500 fps", &refresh_delay, 2);
    options->insertRadioItem("100 fps", &refresh_delay, 10);
    options->insertRadioItem("72 fps", &refresh_delay, 14);
    options->insertRadioItem("30 fps", &refresh_delay, 33);
    options->insertRadioItem("10 fps", &refresh_delay, 100);
    options->insertRadioItem("5 fps", &refresh_delay, 200);
    options->insertSeparator();
    options->insertRadioItem("1/10 speed", &speed, 2);
    options->insertRadioItem("1/2 speed", &speed, 10);
    options->insertRadioItem("1x speed", &speed, 20);
    options->insertRadioItem("2x speed", &speed, 40);
    options->insertRadioItem("5x speed", &speed, 100);
    menu->insertItem("&Options",options);
    m.statusBar();

    QObject::connect(options, SIGNAL(variableChanged(bool*)), &example, SLOT(refresh()));
    QObject::connect(options, SIGNAL(variableChanged(int*)), &example, SLOT(refresh()));
    QObject::connect(&example, SIGNAL(status(const char*)), m.statusBar(), SLOT(message(const char*)));
    m.setCentralWidget(&example);
    app.setMainWidget(&m);
    m.show();

    QTime t;
    t.start();
    app.exec();
    if ( timeit )
	debug("%dms",t.elapsed());
    return 0;
}