Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Wavefront OBJ

kayttaja-4976 [04.10.2006 17:34:27]

#

Ongelma on 3D-mallien käytössä OpenGL:n kanssa. Malliformaatti on tuttu ja turvallinen Wavefront OBJ. Olenkin tässä yrittänyt tehdä koodia niiden lataamiseen ja epäonnistunut surkeasti. En oikeastaan edes tiedä missä virhe piilee kun noita verteksejä on perin monta.

Filu jota yritän saada malliksi
Hakemistossa on myös filun MTL-kirjasto

Mallin pitäisi näyttää tältä (Blenderin mielipide)

Mutta sen pinta näyttääkin tältä

Luokat ovat tässä

struct Verteksi
{
   float x,y,z;
};

struct PintaNelio
{
	int kulma1, kulma2, kulma3, kulma4;
};

class object3D
{
public:
	int kahva;
	PintaNelio pinnat[10000];
	Verteksi VertexPoints [10000];
	Verteksi VertexNormals[10000];
};
int vapaakahva = 0;
object3D Objektit[1];
Verteksi VertexPoints[1];
int pointteja=0;
int tasoja=0;

Latausfunktio:

int LataaObjekti(char *polku)
{
	FILE	*filu;				// Määritellään tiedostopointteri
	char	rivi[100]	="\0";	// Rivin merkkijono
	char	tyyppi;				// Tiedoston rivin tyyppi
	char	tyyppi2;			// Tuplatietoriveille
	float	temppiste_x	= 0;	// Väliaikainen piste X
	float	temppiste_y	= 0;	// Väliaikainen piste Y
	float	temppiste_z	= 0;	// Väliaikainen piste Z
	bool	kauttaviiva = 0;	// Sisältääkö face-definitiot kauttaviivan
	int		i			= 0;	// Indeksi for-looppia varten
	int		kahva		= 0;	// Mallin kahva
	int		temptaso_1	= 0;	// Väliaikainen taso 1
	int		temptaso_2	= 0;	// Väliaikainen taso 2
	int		temptaso_3	= 0;	// Väliaikainen taso 3
	int		temptaso_4	= 0;	// Väliaikainen taso 4
	int		peelo		= 0;	// Peelo
	int		vapaapiste	= 0;	// Vapaa piste
	int		vapaapinta	= 0;	// Vapaa pinta


	filu = fopen(polku, "r");	// Avataan filu

	if (filu == NULL) {			// Tsekataan että filun avaus onnistui
		return 0;				// Jos ei, palautetaan nolla
	}							// Tämä on tärkeää ettei avata filua osoitteesta nolla -> kaataa systeemin


	while(!feof(filu))
	{
		fgets(rivi, 99, filu);
		sscanf(rivi, "%c%c", &tyyppi, &tyyppi2);

		if (tyyppi == '#') {
			tyyppi  = '\0';
			tyyppi2 = '\0';
		}
		else if (tyyppi == 'v' && tyyppi2 == ' ') {	// Pointti

			sscanf(rivi, "%c%c %f %f %f\n", &tyyppi, &tyyppi2, &temppiste_x, &temppiste_y, &temppiste_z);

			Objektit[vapaakahva].VertexPoints[vapaapiste].x = temppiste_x / 3;
			Objektit[vapaakahva].VertexPoints[vapaapiste].y = temppiste_y / 3;
			Objektit[vapaakahva].VertexPoints[vapaapiste].z = temppiste_z / 3;

			temppiste_x = 0;
			temppiste_y = 0;
			temppiste_z = 0;
			vapaapiste++;
			pointteja++;

		}
		else if (tyyppi == 'f' && tyyppi2 == ' ') {	// Face

			for (i=0;i<100;i++) {	// Replasoidaan kauttaviivat välillä
				if (rivi[i] == '/') {
					rivi[i] = ' ';
					kauttaviiva = true;
				}
			}

			if (kauttaviiva) {
				sscanf(rivi, "%c %i %i %i %i %i %i %i %i\n", &tyyppi, &temptaso_1, &temppiste_x, &temptaso_2, &temppiste_y, &temptaso_3, &temppiste_z, &temptaso_4);
			}
			else {
				sscanf(rivi, "%c %i %i %i %i\n", &tyyppi, &temptaso_1, &temptaso_2, &temptaso_3, &temptaso_4);
			}

			Objektit[vapaakahva].pinnat[vapaapinta].kulma1 = temptaso_1;
			Objektit[vapaakahva].pinnat[vapaapinta].kulma2 = temptaso_2;
			Objektit[vapaakahva].pinnat[vapaapinta].kulma3 = temptaso_3;
			Objektit[vapaakahva].pinnat[vapaapinta].kulma4 = temptaso_4;

			temptaso_1 = 0;
			temptaso_2 = 0;
			temptaso_3 = 0;
			temptaso_4 = 0;
			temppiste_x = 0;
			temppiste_y = 0;
			temppiste_z = 0;
			vapaapinta++;
			tasoja++;
			kauttaviiva = false;
			tyyppi = '\0';

		}
		for (i=0; i<100; i++)
			rivi[i] = '\0';
	}

	fclose(filu);
	filu = 0;
	Objektit[vapaakahva].kahva = vapaakahva;
	vapaakahva++;
	return Objektit[vapaakahva].kahva;
}

Ja sitten piirto-osio jossa luulisin ainakin olevan jotain häikkää

for(int i=0; i < tasoja; i++)
{
glBegin(GL_POLYGON);
	glVertex3f(Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma1].x, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma1].y, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma1].z);
	glVertex3f(Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma2].x, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma2].y, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma2].z);
	glVertex3f(Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma3].x, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma3].y, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma3].z);
	glVertex3f(Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma4].x, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma4].y, Objektit[0].VertexPoints[Objektit[0].pinnat[i].kulma4].z);
glEnd();
}

Mitenköhän saisin pallon näkymään oikein siellä kuvassa?

EDIT: Noi kommentit saattaa jossain näyttää vähän hassuilta, mutta tää menee yhteen kirjastoon mitä kaverin pitäisi ymmärtää ja se ei oo kovin guru C++:ssa.

Metabolix [05.10.2006 17:26:24]

#

Vikana on se, että formaatin speksin mukaan tiedoston ensimmäinen verteksi on indeksiltään 1 eikä 0, kuten tässä virheellisesti oletetaan. Eli jossakin kohti pitäisi tämä huomioida.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta