Пример #1
0
        // Returns the contents of a LWOB
        static LightwaveObject ReadObject5(ChunkReader reader)
        {
            // allocate an object and a default layer
            var newObject		= new LightwaveObject();
            var currentLayer	= new Layer();
            newObject.Layers.Add(currentLayer);

            uint pointOffset	= 0;
            uint polygonOffset	= 0;
            uint tagOffset		= 0;

            // process chunks as they're encountered
            while (reader.BytesLeft > 0)
            {
                var id		= reader.ReadID<ChunkType>();
                var cksize	= reader.ReadUInt32();
                cksize += cksize & 1;

                using (var subchunkReader = reader.GetSubChunk(cksize))
                {
                    switch (id)
                    {
                        case ChunkType.ID_PNTS:
                        {
                            pointOffset = (uint)currentLayer.Points.Count;
                            currentLayer.Points.AddRange(
                                        ReadPoints(subchunkReader)							// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_POLS:
                        {
                            polygonOffset = (uint)currentLayer.Polygons.Count;
                            currentLayer.Polygons.AddRange(
                                        ReadPolygons5(subchunkReader, pointOffset)			// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_SRFS:
                        {
                            tagOffset = (uint)newObject.Tags.Count;
                            newObject.Tags.AddRange(
                                        LightwaveObject.ReadTags(subchunkReader)			// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_SURF:
                        {
                            newObject.Surfaces.Add(
                                        Surface.ReadSurface5(subchunkReader, newObject)		// throws exception on failure
                                    );
                            break;
                        }

                        default:
                            Console.WriteLine("Unknown chunk type " + reader.GetIDString((uint)id));
                            break;
                    }
                }
            }

            if (newObject.Tags.Count == 0)
                throw new Exception("No tags found for this layer");	// TODO: create a proper exception class

            uint layer_index = 0;
            foreach (var layer in newObject.Layers)
            {
                layer.CalculateBoundingBox();
                newObject.CalculatePolygonNormals(layer.Points, layer.Polygons);
                newObject.ResolvePointPolygons(layer.Points, layer.Polygons);
                newObject.ResolvePolygonSurfaces(layer.Polygons, newObject.Tags, newObject.Surfaces, layer_index);
                newObject.CalculateVertexNormals(layer.Points, layer.Polygons);
                layer_index++;
            }

            return newObject;
        }
Пример #2
0
        static LightwaveObject ReadObject2(ChunkReader reader)
        {
            // allocate an object and a default layer
            var newObject		= new LightwaveObject();
            var	currentLayer	= new Layer();
            newObject.Layers.Add(currentLayer);

            bool createdLayer	= false;
            uint pointOffset	= 0;
            uint polygonOffset	= 0;
            uint tagOffset		= 0;

            // process chunks as they're encountered
            while (reader.BytesLeft > 0)
            {
                var id = reader.ReadID<ChunkType>();
                var cksize	= reader.ReadUInt32();
                cksize += cksize & 1;

                using (var subchunkReader = reader.GetSubChunk(cksize))
                {
                    switch (id)
                    {
                        case ChunkType.ID_LAYR:
                        {
                            if (createdLayer)
                            {
                                currentLayer = new Layer();
                                newObject.Layers.Add(currentLayer);
                            }

                            createdLayer = true;
                            currentLayer.Index		= subchunkReader.ReadUInt16();
                            currentLayer.Flags		= subchunkReader.ReadUInt16();
                            currentLayer.pivot_x	= subchunkReader.ReadSingle();
                            currentLayer.pivot_y	= subchunkReader.ReadSingle();
                            currentLayer.pivot_z	= subchunkReader.ReadSingle();
                            currentLayer.Name		= subchunkReader.ReadString();
                            if (subchunkReader.BytesLeft > 2)
                                currentLayer.Parent = subchunkReader.ReadUInt16();
                            break;
                        }

                        case ChunkType.ID_PTAG:
                        {
                            ReadPolygonTags(subchunkReader, currentLayer.Polygons, polygonOffset, tagOffset);
                            break;
                        }

                        case ChunkType.ID_BBOX:
                        {
                            currentLayer.bbox_min_x = subchunkReader.ReadSingle();
                            currentLayer.bbox_min_y = subchunkReader.ReadSingle();
                            currentLayer.bbox_min_z = subchunkReader.ReadSingle();
                            currentLayer.bbox_max_x = subchunkReader.ReadSingle();
                            currentLayer.bbox_max_y = subchunkReader.ReadSingle();
                            currentLayer.bbox_max_z = subchunkReader.ReadSingle();
                            break;
                        }

                        case ChunkType.ID_PNTS:
                        {
                            pointOffset = (uint)currentLayer.Points.Count;
                            currentLayer.Points.AddRange(
                                        ReadPoints(subchunkReader)							// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_POLS:
                        {
                            polygonOffset = (uint)currentLayer.Polygons.Count;
                            currentLayer.Polygons.AddRange(
                                        ReadPolygons(subchunkReader, pointOffset)			// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_VMAP:
                        {
                            currentLayer.VertexMaps.Add(
                                        VertexMap.ReadVertexMap(subchunkReader, false)		// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_VMAD:
                        {
                            currentLayer.VertexMaps.Add(
                                        VertexMap.ReadVertexMap(subchunkReader, true)		// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_TAGS:
                        {
                            tagOffset = (uint)newObject.Tags.Count;
                            newObject.Tags.AddRange(
                                        LightwaveObject.ReadTags(subchunkReader)			// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_ENVL:
                        {
                            newObject.Envelopes.Add(
                                        Envelope.ReadEnvelope(subchunkReader)				// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_CLIP:
                        {
                            newObject.Clips.Add(
                                        Clip.ReadClip(subchunkReader)						// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_SURF:
                        {
                            newObject.Surfaces.Add(
                                        Surface.ReadSurface(subchunkReader)					// throws exception on failure
                                    );
                            break;
                        }

                        case ChunkType.ID_DESC: // Description Line - DESC { description-line[S0] }
                        case ChunkType.ID_TEXT: // Commentary Text - TEXT { comment[S0] }
                        case ChunkType.ID_ICON:	// Thumbnail Icon Image - ICON { encoding[U2], width[U2], data[U1] * }
                        case ChunkType.ID_VMPA: // Vertex Map Parameter - VMPA { UV subdivision type[I4], sketch color[I4] }
                            break;
                        default:
                            Console.WriteLine("Unknown chunk type " + reader.GetIDString((uint)id));
                            break;
                    }
                }
            }

            if (newObject.Tags.Count == 0)
                throw new Exception("No tags found for this layer");	// TODO: create a proper exception class

            uint layer_index = 0;
            foreach (var layer in newObject.Layers)
            {
                layer.CalculateBoundingBox();
                newObject.CalculatePolygonNormals(layer.Points, layer.Polygons);
                newObject.ResolvePointPolygons(layer.Points, layer.Polygons);
                newObject.ResolvePolygonSurfaces(layer.Polygons, newObject.Tags, newObject.Surfaces, layer_index);
                newObject.CalculateVertexNormals(layer.Points, layer.Polygons);
                newObject.ResolvePointVertexMaps(layer.Points, layer.VertexMaps);
                newObject.ResolvePolygonVertexMaps(layer.Polygons, layer.VertexMaps);
                layer_index++;
            }

            return newObject;
        }