示例#1
0
文件: l3ds.cpp 项目: pvaut/Z-Flux
void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh)
{
    // variables 
    unsigned short count, t;    
    uint i;
    LTri tri;
    LChunk ch;
    char str[20];
    //uint mat;

    // consistency checks
    if (chunk.id != TRI_FACELIST)
    {
        ErrorMsg("L3DS::ReadFaceList - internal error: wrong chunk passed as parameter");
        return;
    }
    GotoChunk(chunk);
    tri.smoothingGroups = 1;
    // read the number of faces
    count = ReadShort();
    mesh.SetTriangleArraySize(count);
    for (i=0; i<count; i++)
    {
        tri.a = ReadShort();
        tri.b = ReadShort();
        tri.c = ReadShort();
        ReadShort();
        mesh.SetTri(tri, i);
    }
    // now read the optional chunks
    ch = ReadChunk();
    int mat_id;
    while (ch.end <= chunk.end)
    {
        switch (ch.id)
        {
        case TRI_MAT_GROUP:
            ReadASCIIZ(str, 20);
			mat_id=0;
			if (FindMaterial(str)!=NULL)
				mat_id = FindMaterial(str)->GetID();
            mesh.AddMaterial(mat_id);
            count = ReadShort();
            for (i=0; i<count; i++) 
            {
                t = ReadShort();
                mesh.GetTri(t).materialId = mat_id;
            }                
            break;
        case TRI_SMOOTH_GROUP:
            for (i=0; i<mesh.GetTriangleCount(); i++)
                mesh.GetTri(i).smoothingGroups = (ulong) ReadInt();
            break;
        }
        SkipChunk(ch);
        ch = ReadChunk();
    }
}
示例#2
0
/*************
 * DESCRIPTION: read a material-chunk
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParsePropMat(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK    chunk;
	SURFACE  *surf;
	float    perc;
	COLOR    color, diffuse;
	char     buf[80];

	surf = data->link->SurfaceAdd(data->rc);
	if (!surf)
	{
		data->err = ERR_MEM;
		return;
	}
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_PROPNAME:
					ReadASCIIZ(data, buf);
					if (!data->link->SurfaceName(data->rc, surf,buf))
					{
						data->err = ERR_MEM;
						return;
					}
					break;
			case ID_AMBIENT:
					ParseColor(data, &color);
					data->link->SurfaceAmbient(data->rc, surf,color.r,color.g,color.b);
					break;
			case ID_DIFFUSE:
					ParseColor(data, &diffuse);
					data->link->SurfaceDiffuse(data->rc, surf,diffuse.r,diffuse.g,diffuse.b);
					break;
			case ID_SPECULAR:
					ParseColor(data, &color);
					data->link->SurfaceSpecular(data->rc, surf,color.r,color.g,color.b);
					break;
			case ID_SHININESS:
					perc = ParsePercentage(data);
					data->link->SurfaceRefPhong(data->rc, surf,perc*100.f);
					break;
			case ID_TRANSPARENCY:
					perc = ParsePercentage(data);
					data->link->SurfaceTranspar(data->rc, surf,perc*diffuse.r,perc*diffuse.g,perc*diffuse.b);
					break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);
}
示例#3
0
void L3DS::ReadMap(const LChunk &chunk, LMap& map)
{
    LChunk child;
    char str[20];
    GotoChunk(chunk);
    child = ReadChunk();
    while (child.end <= chunk.end)
    {
        switch (child.id)
        {
        case INT_PERCENTAGE:
            map.strength = ReadPercentage(child);
            break;
        case MAT_MAPNAME:
            ReadASCIIZ(str, 20);
            strcpy(map.mapName, str);
            break;
        case MAT_MAP_TILING:
            map.tiling = ReadShort();
            break;
        case MAT_MAP_USCALE:
            map.uScale = ReadFloat();
            break;
        case MAT_MAP_VSCALE:
            map.vScale = ReadFloat();
            break;
        case MAT_MAP_UOFFSET:
            map.uOffset = ReadFloat();
            break;
        case MAT_MAP_VOFFSET:
            map.vOffset = ReadFloat();
            break;
        case MAT_MAP_ANG:
            map.angle = ReadFloat();
            break;
        }
        SkipChunk(child);
        child = ReadChunk();
    }
}
示例#4
0
void L3DS::ReadKeyframeData(const LChunk &parent)
{
    uint frames = 0;

    LChunk node_hdr;
    node_hdr.id = NODE_HDR;

    char str[20];
    LMesh *mesh;

    GotoChunk(parent);
    if (!FindChunk(node_hdr, parent))
        return;
    GotoChunk(node_hdr);
    ReadASCIIZ(str, 19);
    mesh = FindMesh(str);
    if (mesh == 0)
        return;
    GotoChunk(parent);

    // read the pivot
    //LVector3 pivot = zero3;

    LChunk pivotchunk;
    pivotchunk.id = PIVOT;
    if (FindChunk(pivotchunk, parent))
    {
        GotoChunk(pivotchunk);
        /*pivot.x =*/ ReadFloat();
        /*pivot.y =*/ ReadFloat();
        /*pivot.z =*/ ReadFloat();
    }
    GotoChunk(parent);

    // read frame 0 from the position track
    //LVector3 pos = zero3;

    frames = 0;

    LChunk poschunk;
    poschunk.id = POS_TRACK_TAG;
    if (FindChunk(poschunk, parent))
    {
        GotoChunk(poschunk);
        // read the trackheader structure
        ReadShort();
        ReadInt();
        ReadInt();
        frames = ReadInt();
        if (frames > 0)
        {
            ReadKeyheader();
            /*pos.x =*/ ReadFloat();
            /*pos.y =*/ ReadFloat();
            /*pos.z =*/ ReadFloat();
        }
    }
    GotoChunk(parent);

    // now read the rotation track
    //LVector4 rot = zero4;

    LChunk rotchunk;
    rotchunk.id = ROT_TRACK_TAG;

    frames = 0;
    if (FindChunk(rotchunk, parent))
    {
        GotoChunk(rotchunk);
        // read the trackheader structure
        ReadShort();
        ReadInt();
        ReadInt();
        frames = ReadInt();
        if (frames > 0)
        {
            ReadKeyheader();
            /*rot.x =*/ ReadFloat();
            /*rot.y =*/ ReadFloat();
            /*rot.z =*/ ReadFloat();
            /*rot.w =*/ ReadFloat();
        }
    }
    GotoChunk(parent);

    // now read the scaling chunk
    //LVector3 scale;
    //scale.x = 1;
    //scale.y = 1;
    //scale.z = 1;

    LChunk scalechunk;
    scalechunk.id = SCL_TRACK_TAG;

    frames = 0;

    if (FindChunk(scalechunk, parent))
    {
        GotoChunk(scalechunk);
        // read the trackheader structure
        ReadShort();
        ReadInt();
        ReadInt();
        frames = ReadInt();
        if (frames > 0)
        {
            ReadKeyheader();
            /*scale.x =*/ ReadFloat();
            /*scale.y =*/ ReadFloat();
            /*scale.z =*/ ReadFloat();
        }
    }
    GotoChunk(parent);
}
示例#5
0
void L3DS::ReadMaterial(const LChunk &parent)
{
    // variables
    LChunk chunk;
    LChunk child;
    char str[30];
    LMaterial mat;
    short sh;

    GotoChunk(parent);

    chunk = ReadChunk();
    while (chunk.end <= parent.end)
    {
        switch (chunk.id)
        {
        case MAT_NAME:
            ReadASCIIZ(str, 30);
            mat.SetName(str);
            break;
        case MAT_AMBIENT:
            child = ReadChunk();
            mat.SetAmbientColor(ReadColor(child));
            break;
        case MAT_DIFFUSE:
            child = ReadChunk();
            mat.SetDiffuseColor(ReadColor(child));
            break;
        case MAT_SPECULAR:
            child = ReadChunk();
            mat.SetSpecularColor(ReadColor(child));
            break;
        case MAT_SHININESS:
            child = ReadChunk();
            mat.SetShininess(ReadPercentage(child));
            break;
        case MAT_TRANSPARENCY:
            child = ReadChunk();
            mat.SetTransparency(ReadPercentage(child));
            break;
        case MAT_SHADING:
            sh = ReadShort();
            switch (sh)
            {
            case 0:
                mat.SetShadingType(sWireframe);
                break;
            case 1:
                mat.SetShadingType(sFlat);
                break;
            case 2:
                mat.SetShadingType(sGouraud);
                break;
            case 3:
                mat.SetShadingType(sPhong);
                break;
            case 4:
                mat.SetShadingType(sMetal);
                break;
            }
            break;
        case MAT_WIRE:
            mat.SetShadingType(sWireframe);
            break;
        case MAT_TEXMAP:
            ReadMap(chunk, mat.GetTextureMap1());
            break;
        case MAT_TEX2MAP:
            ReadMap(chunk, mat.GetTextureMap2());
            break;
        case MAT_OPACMAP:
            ReadMap(chunk, mat.GetOpacityMap());
            break;
        case MAT_BUMPMAP:
            ReadMap(chunk, mat.GetBumpMap());
            break;
        case MAT_SPECMAP:
            ReadMap(chunk, mat.GetSpecularMap());
            break;
        case MAT_REFLMAP:
            // AMZ not really a bugfix but it seems to work!
#if 1
            ReadMap(chunk, mat.GetReflectionMap());
#else
            child = ReadChunk();
            mat.GetReflectionMap().strength = ReadPercentage(child);
            SkipChunk(child);
            child = ReadChunk();
            if (child.id != MAT_MAPNAME)
            {
                fprintf(stderr, "L3DS::ReadMaterial - error, expected chunk not found");
                return;
            }
            ReadASCIIZ(str, 30);
            if (strcmp(str, "") == 0)
                strcpy(mat.GetReflectionMap().mapName, "auto");
#endif
            break;
        }

        SkipChunk(chunk);
        chunk = ReadChunk();
    }
    m_materials.push_back(mat);
    m_materials[m_materials.size()-1].SetID(uint(m_materials.size())-1);
}
示例#6
0
bool L3DS::Read3DS()
{
    LChunk mainchunk;
    LChunk edit;
    edit.id = EDIT3DS;
    mainchunk = ReadChunk();
    if (mainchunk.id != MAIN3DS)
    {
        fprintf(stderr, "L3DS::Read3DS - wrong file format");
        return false;
    }
    if (!FindChunk(edit, mainchunk))
        return false;
    LChunk obj;
    LChunk ml;

    GotoChunk(edit);
    obj.id = MAT_ENTRY;
    while (FindChunk(obj, edit))
    {
        ReadMaterial(obj);
        SkipChunk(obj);
    }
    GotoChunk(edit);

    obj.id = EDIT_OBJECT;
    {
        while (FindChunk(obj, edit))
        {
            ReadASCIIZ(m_objName, 99);
            ml = ReadChunk();
            if (ml.id == OBJ_TRIMESH)
                ReadMesh(ml);
            else
            if (ml.id == OBJ_LIGHT)
                ReadLight(ml);
            else
            if (ml.id == OBJ_CAMERA)
                ReadCamera(ml);
            SkipChunk(obj);
        }
    }

    // read the keyframer data here to find out correct object orientation

    LChunk keyframer;
    keyframer.id = KFDATA;

    LChunk objtrack;
    objtrack.id = OBJECT_NODE_TAG;

    GotoChunk(mainchunk);
    if (FindChunk(keyframer, mainchunk))
    {   // keyframer chunk is present
        GotoChunk(keyframer);
        while (FindChunk(objtrack, keyframer))
        {
            ReadKeyframeData(objtrack);
            SkipChunk(objtrack);
        }
    }

    for (uint i=0; i<m_meshes.size(); i++)
        m_meshes[i].Optimize(m_optLevel);
    m_pos = 0;
    strcpy(m_objName, "");
    return true;
}
示例#7
0
/*************
 * DESCRIPTION: -
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParseNamedObject(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK     chunk;
	TRIANGLE *triangle;
	TRILIST  *ph1,*ph2;
	float     angle;
	UWORD     p1, p2, p3;
	UWORD     *edges;
	int       i, h;

	ReadASCIIZ(data, data->ObjName);
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_TRIANGLE:
				ParseTriObject(data, &chunk);
				break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);

	if (data->TriList && (data->link->type == LINK_RENDERER))
	{
		// go through all vertices and calculate normals (only for renderer)
		for (i = 0; i < data->pointcount; i++)
		{
			data->VertNorms[i].x = data->VertNorms[i].y = data->VertNorms[i].z = 0.f;
			ph1 = data->TriList[i];
			while (ph1)
			{
				for (ph2 = ph1->next; ph2 != NULL; ph2 = ph2->next)
				{
					if (!ph1->flag || !ph2->flag)
					{
						// test angle between two triangles
						angle = VecAngle(data->TriNorms[ph1->tri], data->TriNorms[ph2->tri]);
//                if (angle < 2*PI && angle > /*cos_*/smooth_angle)
						if (angle >0 && angle < /*cos_*/data->smooth_angle)
						{
							if (!ph1->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph1->tri], &data->VertNorms[i]);
								ph1->flag = TRUE;
								data->TriSmooth[ph1->tri] = TRUE;
							}
							if (!ph2->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph2->tri], &data->VertNorms[i]);
								ph2->flag = TRUE;
								data->TriSmooth[ph2->tri] = TRUE;
							}
						}
					}
				}
				ph2 = ph1;
				ph1 = ph1->next;
				delete ph2;
			}
			VecNormalize(&data->VertNorms[i]);
		}
	}

	if (data->face)
	{
		data->link->ObjectBegin(data->rc);

		data->defaultsurface = data->link->SurfaceAdd(data->rc);
		if (!data->defaultsurface)
		{
			data->err = ERR_MEM;
			return;
		}

		data->link->SurfaceName(data->rc, data->defaultsurface, "default");
		data->link->SurfaceDiffuse(data->rc, data->defaultsurface, 0.9f, 0.9f, 0.9f);
		data->link->SurfaceAmbient(data->rc, data->defaultsurface, 0.1f, 0.1f, 0.1f);
		data->link->SurfaceRefPhong(data->rc, data->defaultsurface, 49.f);

		triangle = data->link->TriangleAdd(data->rc, data->facecount,data->defaultsurface,data->mainactor);
		if (!triangle)
		{
			data->err = ERR_MEM;
			return;
		}
		if (data->link->type == LINK_SCENARIO)
		{  // modeler needs points,edges and faces seperate
			if (data->link->TriangleAddPoints(data->rc, data->pointcount,data->points) == -1)
			{
				data->err = ERR_MEM;
				return;
			}
			edges = new UWORD[data->facecount*6];
			if (!edges)
			{
				data->err = ERR_MEM;
				return;
			}
			for (i = 0; i < data->facecount; i++)
			{
				h = i*6;
				edges[h++] = data->face[i].p1;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p1;
			}
			if (data->link->TriangleAddEdges(data->rc, data->facecount*3,edges) == -1)
			{
				delete edges;
				data->err = ERR_MEM;
				return;
			}
			delete edges;
		}
		for (i = 0; i < data->facecount; i++)
		{
			p1 = data->face[i].p1;
			p2 = data->face[i].p3;
			p3 = data->face[i].p2;

			if(data->replacesurface)
				data->link->TriangleSurface(data->rc, triangle, data->replacesurface);
			else
			{
				if(!data->material[i])
					data->link->TriangleSurface(data->rc, triangle, data->defaultsurface);
				else
					data->link->TriangleSurface(data->rc, triangle, data->material[i]);
			}

			if (data->link->type == LINK_SCENARIO)
			{  // modeler needs edges
				data->link->TriangleSetEdges(data->rc, triangle,i*3,i*3+1,i*3+2);
			}
			else
			{
				// raystorm renderer needs triangles and normals
				data->link->TrianglePoints(data->rc, triangle,&data->points[p1],&data->points[p2],&data->points[p3]);

				if (!VecZero(data->TriNorms[i]))
				{
					// generate smooth triangle when smooth flag is set
					if (data->TriSmooth[i])
					{
						data->link->TriangleVNorm(data->rc, triangle,
							VecZero(data->VertNorms[p1]) ? &data->TriNorms[i] : &data->VertNorms[p1],
							VecZero(data->VertNorms[p2]) ? &data->TriNorms[i] : &data->VertNorms[p2],
							VecZero(data->VertNorms[p3]) ? &data->TriNorms[i] : &data->VertNorms[p3]);
					}
				}
				if(data->mapping)
				{
					data->link->TriangleUV(data->rc, triangle,
						&data->mapping[p1], &data->mapping[p2], &data->mapping[p3]);
				}
			}

			// next triangle
			triangle = data->link->TriangleGetNext(data->rc, triangle);
		}
		data->link->ObjectEnd(data->rc);
	}

	CleanupMesh(data);
}
示例#8
0
/*************
 * DESCRIPTION: read faces of object
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParseFaces(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK    chunk;
	UWORD    i, matcount, index, p1, p2, p3;
	VECTOR   e1, e2;
	SURFACE  *s;
	TRILIST  *hp;
	char     buf[80];

	ReadWord(data, (WORD *)&data->facecount, 1); // read number of faces

	if (data->facecount == 0)
		return;

	data->face = new FACE3DS[data->facecount];
	if (!data->face)
	{
		data->err = ERR_MEM;
		return;
	}
	if (!data->replacesurface)
	{
		data->material = (SURFACE **)malloc(sizeof(SURFACE *)*data->facecount);
		if (!data->material)
		{
			data->err = ERR_MEM;
			return;
		}
	}

	ReadWord(data, (WORD *)data->face, 4*data->facecount);   // read faces

	if (data->link->type == LINK_RENDERER)
	{
		// do it for renderer only

		data->VertNorms = new VECTOR[data->pointcount];
		if (!data->VertNorms)
		{
			data->err = ERR_MEM;
			return;
		}

		data->TriNorms = new VECTOR[data->facecount];
		if (!data->TriNorms)
		{
			data->err = ERR_MEM;
			return;
		}
		memset(data->VertNorms, 0, sizeof(VECTOR)*data->pointcount);   // Init normals

		data->TriSmooth = new UBYTE[data->facecount];
		if (!data->TriSmooth)
		{
			data->err = ERR_MEM;
			return;
		}

		for (i = 0; i < data->facecount; i++)
		{
			if (data->replacesurface)
				data->material[i] = data->replacesurface;
			else
				data->material[i] = NULL;

			data->TriSmooth[i] = FALSE;
			// get three points for the triangle
			p1 = data->face[i].p1;
			p2 = data->face[i].p3;
			p3 = data->face[i].p2;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p1];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p1] = hp;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p2];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p2] = hp;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p3];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p3] = hp;

			// calculate normal of triangle
			VecSub(&data->points[p3], &data->points[p1], &e1);
			VecSub(&data->points[p2], &data->points[p1], &e2);
			VecNormCross(&e1, &e2, &data->TriNorms[i]);
		}
	}
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_MSHMATGROUP:
					if (!data->replacesurface)
					{
						ReadASCIIZ(data, buf);
						s = data->link->SurfaceGetByName(data->rc, buf);
						ReadWord(data, (WORD*)&matcount, 1);
						for (i = 0; i < matcount; i++)
						{
							ReadWord(data, (WORD*)&index, 1);
							data->material[index] = s;
						}
					}
					break;
			case ID_SMOOTHGROUP: // no info about this group
					break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);
}