void DeformationGraph::BuildGraph()
{
	GenerateRandomNodes();
	GenerateEdges();
}
HRESULT InitScene()
{
	HRESULT hr;

	SetWindowText(hwnd, TITLE);

	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/marble.dds", &texture1));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/wood2.jpg", &texture2));
	MYVALID(DXCreateEffect("../media/shaders/ambient.fx", device, &ambient));
	MYVALID(DXCreateEffect("../media/shaders/blinnphong.fx", device, &specular));
	MYVALID(DXCreateEffect("../media/shaders/extrude.fx", device, &extrude));

	MYVALID(device->CreateTexture(512, 128, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &text, NULL));
	MYVALID(DXCreateTexturedBox(device, D3DXMESH_MANAGED, &shadowreceiver));

	// box
	MYVALID(DXCreateTexturedBox(device, D3DXMESH_MANAGED, &objects[0].object));
	MYVALID(DXCreateCollisionBox(device, D3DXMESH_SYSTEMMEM, &objects[0].caster));

	D3DXMatrixTranslation(&objects[0].world, -1.5f, 0.55f, 1.2f);

	MYVALID(device->CreateVertexBuffer(VOLUME_NUMVERTICES(objects[0].caster->GetNumVertices()) * sizeof(D3DXVECTOR4), D3DUSAGE_DYNAMIC, D3DFVF_XYZW, D3DPOOL_DEFAULT, &objects[0].vertices, NULL));
	MYVALID(device->CreateIndexBuffer(VOLUME_NUMINDICES(objects[0].caster->GetNumFaces()) * sizeof(WORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &objects[0].indices, NULL));

	// sphere
	MYVALID(DXCreateTexturedSphere(device, 0.5f, 30, 30, D3DXMESH_SYSTEMMEM, &objects[1].object));
	MYVALID(DXCreateCollisionSphere(device, 0.5f, 30, 30, D3DXMESH_SYSTEMMEM, &objects[1].caster));

	D3DXMatrixTranslation(&objects[1].world, 1.0f, 0.55f, 0.7f);

	MYVALID(device->CreateVertexBuffer(VOLUME_NUMVERTICES(objects[1].caster->GetNumVertices()) * sizeof(D3DXVECTOR4), D3DUSAGE_DYNAMIC, D3DFVF_XYZW, D3DPOOL_DEFAULT, &objects[1].vertices, NULL));
	MYVALID(device->CreateIndexBuffer(VOLUME_NUMINDICES(objects[1].caster->GetNumFaces()) * sizeof(WORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &objects[1].indices, NULL));

	// L shape
	MYVALID(DXCreateTexturedLShape(device, D3DXMESH_MANAGED, &objects[2].object));
	MYVALID(DXCreateCollisionLShape(device, D3DXMESH_SYSTEMMEM, &objects[2].caster));

	D3DXMatrixTranslation(&objects[2].world, 0, 0.55f, -1);

	MYVALID(device->CreateVertexBuffer(VOLUME_NUMVERTICES(objects[2].caster->GetNumVertices()) * sizeof(D3DXVECTOR4), D3DUSAGE_DYNAMIC, D3DFVF_XYZW, D3DPOOL_DEFAULT, &objects[2].vertices, NULL));
	MYVALID(device->CreateIndexBuffer(VOLUME_NUMINDICES(objects[2].caster->GetNumFaces()) * sizeof(WORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &objects[2].indices, NULL));

#if 0
	D3DXMATERIAL defmat;

	defmat.pTextureFilename = 0;
	defmat.MatD3D.Ambient = D3DXCOLOR(1, 1, 1, 1);
	defmat.MatD3D.Diffuse = D3DXCOLOR(1, 1, 1, 1);
	defmat.MatD3D.Specular = D3DXCOLOR(1, 1, 1, 1);
	defmat.MatD3D.Emissive = D3DXCOLOR(0, 0, 0, 0);
	defmat.MatD3D.Power = 20;

	DXSaveMeshToQM("../media/meshes10/box.qm", objects[0].object, &defmat, 1);
	DXSaveMeshToQM("../media/meshes10/collisionbox.qm", objects[0].caster, &defmat, 1);

	DXSaveMeshToQM("../media/meshes10/sphere.qm", objects[1].object, &defmat, 1);
	DXSaveMeshToQM("../media/meshes10/collisionsphere.qm", objects[1].caster, &defmat, 1);

	DXSaveMeshToQM("../media/meshes10/lshape.qm", objects[2].object, &defmat, 1);
	DXSaveMeshToQM("../media/meshes10/collisionlshape.qm", objects[2].caster, &defmat, 1);
#endif

	// generate edges
	std::cout << "Generating edge info...\n";

	for( int i = 0; i < NUM_OBJECTS; ++i )
		GenerateEdges(objects[i].edges, objects[i].caster);

	// shadow volume decl
	D3DVERTEXELEMENT9 elem[] =
	{
		{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
		D3DDECL_END()
	};

	MYVALID(device->CreateVertexDeclaration(elem, &shadowdecl));

	// effect
	specular->SetFloat("ambient", 0);

	cameraangle = D3DXVECTOR2(0.78f, 0.78f);
	lightangle = D3DXVECTOR2(2.8f, 0.78f);

	DXRenderText("Use mouse to rotate camera and light\n\n1: draw silhouette\n2: draw shadow volume", text, 512, 128);

	return S_OK;
}
Example #3
0
void Entity::DrawOrGetDistance(void) {
    if(!IsVisible()) return;

    Group *g = SK.GetGroup(group);

    switch(type) {
        case POINT_N_COPY:
        case POINT_N_TRANS:
        case POINT_N_ROT_TRANS:
        case POINT_N_ROT_AA:
        case POINT_IN_3D:
        case POINT_IN_2D: {
            Vector v = PointGetNum();
            dogd.refp = v;

            if(dogd.drawing) {
                double s = 3.5;
                Vector r = SS.GW.projRight.ScaledBy(s/SS.GW.scale);
                Vector d = SS.GW.projUp.ScaledBy(s/SS.GW.scale);

                ssglColorRGB(Style::Color(Style::DATUM));
                ssglDepthRangeOffset(6);
                glBegin(GL_QUADS);
                    ssglVertex3v(v.Plus (r).Plus (d));
                    ssglVertex3v(v.Plus (r).Minus(d));
                    ssglVertex3v(v.Minus(r).Minus(d));
                    ssglVertex3v(v.Minus(r).Plus (d));
                glEnd();
                ssglDepthRangeOffset(0);
            } else {
                Point2d pp = SS.GW.ProjectPoint(v);
                dogd.dmin = pp.DistanceTo(dogd.mp) - 6;
            }
            break;
        }

        case NORMAL_N_COPY:
        case NORMAL_N_ROT:
        case NORMAL_N_ROT_AA:
        case NORMAL_IN_3D:
        case NORMAL_IN_2D: {
            int i;
            for(i = 0; i < 2; i++) {
                if(i == 0 && !SS.GW.showNormals) {
                    // When the normals are hidden, we will continue to show
                    // the coordinate axes at the bottom left corner, but
                    // not at the origin.
                    continue;
                }

                hRequest hr = h.request();
                // Always draw the x, y, and z axes in red, green, and blue;
                // brighter for the ones at the bottom left of the screen,
                // dimmer for the ones at the model origin.
                int f = (i == 0 ? 100 : 255);
                if(hr.v == Request::HREQUEST_REFERENCE_XY.v) {
                    ssglColorRGB(RGBi(0, 0, f));
                } else if(hr.v == Request::HREQUEST_REFERENCE_YZ.v) {
                    ssglColorRGB(RGBi(f, 0, 0));
                } else if(hr.v == Request::HREQUEST_REFERENCE_ZX.v) {
                    ssglColorRGB(RGBi(0, f, 0));
                } else {
                    ssglColorRGB(Style::Color(Style::NORMALS));
                    if(i > 0) break;
                }

                Quaternion q = NormalGetNum();
                Vector tail;
                if(i == 0) {
                    tail = SK.GetEntity(point[0])->PointGetNum();
                    glLineWidth(1);
                } else {
                    // Draw an extra copy of the x, y, and z axes, that's
                    // always in the corner of the view and at the front.
                    // So those are always available, perhaps useful.
                    double s = SS.GW.scale;
                    double h = 60 - SS.GW.height/2;
                    double w = 60 - SS.GW.width/2;
                    tail = SS.GW.projRight.ScaledBy(w/s).Plus(
                           SS.GW.projUp.   ScaledBy(h/s)).Minus(SS.GW.offset);
                    ssglDepthRangeLockToFront(true);
                    glLineWidth(2);
                }

                Vector v = (q.RotationN()).WithMagnitude(50/SS.GW.scale);
                Vector tip = tail.Plus(v);
                LineDrawOrGetDistance(tail, tip);

                v = v.WithMagnitude(12/SS.GW.scale);
                Vector axis = q.RotationV();
                LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis, 0.6)));
                LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis,-0.6)));
            }
            ssglDepthRangeLockToFront(false);
            break;
        }

        case DISTANCE:
        case DISTANCE_N_COPY:
            // These are used only as data structures, nothing to display.
            break;

        case WORKPLANE: {
            Vector p;
            p = SK.GetEntity(point[0])->PointGetNum();

            Vector u = Normal()->NormalU();
            Vector v = Normal()->NormalV();

            double s = (min(SS.GW.width, SS.GW.height))*0.45/SS.GW.scale;

            Vector us = u.ScaledBy(s);
            Vector vs = v.ScaledBy(s);

            Vector pp = p.Plus (us).Plus (vs);
            Vector pm = p.Plus (us).Minus(vs);
            Vector mm = p.Minus(us).Minus(vs), mm2 = mm;
            Vector mp = p.Minus(us).Plus (vs);

            glLineWidth(1);
            ssglColorRGB(Style::Color(Style::NORMALS));
            glEnable(GL_LINE_STIPPLE);
            glLineStipple(3, 0x1111);
            if(!h.isFromRequest()) {
                mm = mm.Plus(v.ScaledBy(60/SS.GW.scale));
                mm2 = mm2.Plus(u.ScaledBy(60/SS.GW.scale));
                LineDrawOrGetDistance(mm2, mm);
            }
            LineDrawOrGetDistance(pp, pm);
            LineDrawOrGetDistance(pm, mm2);
            LineDrawOrGetDistance(mm, mp);
            LineDrawOrGetDistance(mp, pp);
            glDisable(GL_LINE_STIPPLE);

            char *str = DescriptionString()+5;
            double th = DEFAULT_TEXT_HEIGHT;
            if(dogd.drawing) {
                ssglWriteText(str, th, mm2, u, v, NULL, NULL);
            } else {
                Vector pos = mm2.Plus(u.ScaledBy(ssglStrWidth(str, th)/2)).Plus(
                                      v.ScaledBy(ssglStrHeight(th)/2));
                Point2d pp = SS.GW.ProjectPoint(pos);
                dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 10);
                // If a line lies in a plane, then select the line, not
                // the plane.
                dogd.dmin += 3;
            }
            break;
        }

        case LINE_SEGMENT:
        case CIRCLE:
        case ARC_OF_CIRCLE:
        case CUBIC:
        case CUBIC_PERIODIC:
        case TTF_TEXT:
            // Nothing but the curve(s).
            break;

        case FACE_NORMAL_PT:
        case FACE_XPROD:
        case FACE_N_ROT_TRANS:
        case FACE_N_TRANS:
        case FACE_N_ROT_AA:
            // Do nothing; these are drawn with the triangle mesh
            break;

        default:
            oops();
    }

    // And draw the curves; generate the rational polynomial curves for
    // everything, then piecewise linearize them, and display those.
    SEdgeList sel;
    ZERO(&sel);
    GenerateEdges(&sel, true);
    int i;
    for(i = 0; i < sel.l.n; i++) {
        SEdge *se = &(sel.l.elem[i]);
        LineDrawOrGetDistance(se->a, se->b, true);
    }
    sel.Clear();
}