public static VertexMap ReadVertexMap(ChunkReader reader, bool perpoly) { var type = reader.ReadID<VertexMapType>(); var dimensions = reader.ReadUInt16(); var name = reader.ReadString(); var vertex_map = new VertexMap(type, name, perpoly); var vertex_indices = new List<uint>(); var polygon_indices = new List<uint>(); var values = new List<float[]>(); // fill in the vertex-map values while (reader.BytesLeft > 0) { vertex_indices.Add(reader.ReadVariableLengthIndex()); if (perpoly) polygon_indices.Add(reader.ReadVariableLengthIndex()); var pointValues = new float[dimensions]; for (var j = 0; j < dimensions; j++) pointValues[j] = reader.ReadSingle(); values.Add(pointValues); } vertex_map.Values = values.ToArray(); vertex_map.vertex_index = vertex_indices.ToArray(); if (perpoly) vertex_map.polygon_index = polygon_indices.ToArray(); return vertex_map; }
// LWOB public static Surface ReadSurface5(ChunkReader reader, LightwaveObject obj) { var surf = new Surface(); surf.name = reader.ReadString(); Texture tex = null; LightwavePlugin shdr = null; float[] v = new float[3]; uint flags = 0; // process subchunks as they're encountered while (reader.BytesLeft > 0) { var id = reader.ReadID<SurfaceParameter>(); var sz = reader.ReadUInt16(); sz += (ushort)(sz & 1); using (var subChunkReader = reader.GetSubChunk(sz)) { switch (id) { case SurfaceParameter.ID_COLR: { surf.color.Red = subChunkReader.ReadUInt8() / 255.0f; surf.color.Green = subChunkReader.ReadUInt8() / 255.0f; surf.color.Blue = subChunkReader.ReadUInt8() / 255.0f; break; } case SurfaceParameter.ID_FLAG: { flags = subChunkReader.ReadUInt16(); if ((flags & 4) != 0) surf.smooth = 1.56207f; if ((flags & 8) != 0) surf.color_hilite.value = 1.0f; if ((flags & 16) != 0) surf.color_filter.value = 1.0f; if ((flags & 128) != 0) surf.dif_sharp.value = 0.5f; if ((flags & 256) != 0) surf.sideflags = 3; if ((flags & 512) != 0) surf.add_trans.value = 1.0f; break; } case SurfaceParameter.ID_LUMI: { surf.luminosity.Value = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_VLUM: { surf.luminosity.Value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_DIFF: { surf.diffuse.Value = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_VDIF: { surf.diffuse.Value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_SPEC: { surf.specularity.Value = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_VSPC: { surf.specularity.Value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_GLOS: { surf.glossiness.Value = (float)Math.Log(subChunkReader.ReadUInt16()) / 20.7944f; break; } case SurfaceParameter.ID_SMAN: { surf.smooth = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_REFL: { surf.reflection.values.Value = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_RFLT: { surf.reflection.options = subChunkReader.ReadUInt16(); break; } case SurfaceParameter.ID_RIMG: { var s = subChunkReader.ReadString(); surf.reflection.clip_index = AddClip(s, obj.Clips); surf.reflection.options = 3; break; } case SurfaceParameter.ID_RSAN: { surf.reflection.seam_angle = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TRAN: { surf.transparency.values.Value = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_RIND: { surf.eta.Value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_BTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.bump.textures.Add(tex); break; } case SurfaceParameter.ID_CTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.color.textures.Add(tex); break; } case SurfaceParameter.ID_DTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.diffuse.textures.Add(tex); break; } case SurfaceParameter.ID_LTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.luminosity.textures.Add(tex); break; } case SurfaceParameter.ID_RTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.reflection.values.textures.Add(tex); break; } case SurfaceParameter.ID_STEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.specularity.textures.Add(tex); break; } case SurfaceParameter.ID_TTEX: { var s = subChunkReader.ReadString(sz);//.getbytes((uint)sz); tex = ParseTexture(s); surf.transparency.values.textures.Add(tex); break; } case SurfaceParameter.ID_TFLG: { if (tex == null) return null; flags = subChunkReader.ReadUInt16(); int i = 0; if ((flags & 1) != 0) i = 0; if ((flags & 2) != 0) i = 1; if ((flags & 4) != 0) i = 2; tex.axis = (ushort)i; if (tex.Type == TextureType.ID_IMAP) tex.imap.axis = i; else tex.proc.axis = i; if ((flags & 8) != 0) tex.tmap.CoordinateSystem = 1; if ((flags & 16) != 0) tex.negative = 1; if ((flags & 32) != 0) tex.imap.pblend = 1; if ((flags & 64) != 0) { tex.imap.aa_strength = 1.0f; tex.imap.aas_flags = 1; } break; } case SurfaceParameter.ID_TSIZ: { tex.tmap.Size.values[0] = subChunkReader.ReadSingle(); tex.tmap.Size.values[1] = subChunkReader.ReadSingle(); tex.tmap.Size.values[2] = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TCTR: { tex.tmap.Center.values[0] = subChunkReader.ReadSingle(); tex.tmap.Center.values[1] = subChunkReader.ReadSingle(); tex.tmap.Center.values[2] = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TFAL: { tex.tmap.FallOff.values[0] = subChunkReader.ReadSingle(); tex.tmap.FallOff.values[1] = subChunkReader.ReadSingle(); tex.tmap.FallOff.values[2] = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TVEL: { for (var i = 0; i < 3; i++) v[i] = subChunkReader.ReadSingle(); tex.tmap.Center.envelope_index = AddTextureVelocity(tex.tmap.Center.values, v, obj.Envelopes); break; } case SurfaceParameter.ID_TCLR: { if (tex.Type == TextureType.ID_PROC) { tex.proc.value_0 = subChunkReader.ReadUInt8() / 255.0f; tex.proc.value_1 = subChunkReader.ReadUInt8() / 255.0f; tex.proc.value_2 = subChunkReader.ReadUInt8() / 255.0f; } break; } case SurfaceParameter.ID_TVAL: { tex.proc.value_0 = subChunkReader.ReadSInt16() / 256.0f; break; } case SurfaceParameter.ID_TAMP: { if (tex.Type == TextureType.ID_IMAP) tex.imap.amplitude.value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TIMG: { var s = subChunkReader.ReadString(); tex.imap.clip_index = AddClip(s, obj.Clips); break; } case SurfaceParameter.ID_TAAS: { tex.imap.aa_strength = subChunkReader.ReadSingle(); tex.imap.aas_flags = 1; break; } case SurfaceParameter.ID_TREF: { tex.tmap.ReferenceObject = subChunkReader.ReadString((uint)sz);//.getbytes((uint)sz); break; } case SurfaceParameter.ID_TOPC: { tex.opacity.value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TFP0: { if (tex.Type == TextureType.ID_IMAP) tex.imap.wrapw.value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_TFP1: { if (tex.Type == TextureType.ID_IMAP) tex.imap.wraph.value = subChunkReader.ReadSingle(); break; } case SurfaceParameter.ID_SHDR: { shdr = new LightwavePlugin(); if (shdr == null) return null; shdr.name = subChunkReader.ReadString((uint)sz); surf.shader.Add(shdr); break; } case SurfaceParameter.ID_SDAT: { if (shdr == null) return null; shdr.data = subChunkReader.ReadBytes(sz); break; } default: Console.WriteLine("Unknown surface parameter type " + reader.GetIDString((uint)id)); break; } } } return surf; }
public static LightwavePlugin ReadShader(ChunkReader reader) { var shader = new LightwavePlugin(); var hsz = reader.ReadUInt16(); // Q: example code does this, but can't find this in documentation? shader.ord = reader.ReadString(); using (var headerReader = reader.GetSubChunk(hsz)) { while (headerReader.BytesLeft > 0) { var id = headerReader.ReadID<PluginType>(); var sz = headerReader.ReadUInt16(); sz += (ushort)(sz & 1); hsz -= sz; if (id == PluginType.ID_ENAB) { shader.flags = headerReader.ReadUInt16(); break; } } } while (reader.BytesLeft > 0) { var id = reader.ReadID<PluginType>(); var sz = reader.ReadUInt16(); sz += (ushort)(sz & 1); using (var subChunkReader = reader.GetSubChunk(sz)) { switch (id) { case PluginType.ID_FUNC: { shader.name = subChunkReader.ReadString(); shader.data = subChunkReader.ReadBytes((uint)subChunkReader.BytesLeft); break; } default: //Console.WriteLine("Unknown shader type " + reader.GetIDString((uint)id)); break; } } } return shader; }
public static Surface ReadSurface(ChunkReader reader) { // allocate the Surface structure var surf = new Surface(); // names surf.name = reader.ReadString(); surf.srcname = reader.ReadString(); // process subchunks as they're encountered while (reader.BytesLeft > 0) { var id = reader.ReadID<SurfaceParameter>(); var sz = reader.ReadUInt16(); sz += (ushort)(sz & 1); using (var subChunkReader = reader.GetSubChunk(sz)) { switch (id) { // Vertex Color Map - VCOL { intensity[FP4], envelope[VX], vmap-type[ID4], name[S0] } // The vertex color map subchunk identifies an RGB or RGBA VMAP that will be used to color the surface case SurfaceParameter.ID_VCOL: { var intensity = subChunkReader.ReadSingle(); var envelope_index = subChunkReader.ReadVariableLengthIndex(); var vmap_type = subChunkReader.ReadUInt32(); var name = subChunkReader.ReadString(); break; } case SurfaceParameter.ID_CMNT: // Not mentioned in LWO documentation, maybe means 'comment'? { break; } case SurfaceParameter.ID_VERS: // Not mentioned in LWO documentation, maybe means 'version'? { break; } case SurfaceParameter.ID_NODS: // Not mentioned in LWO documentation, maybe means 'nodes'? { break; } case SurfaceParameter.ID_COLR: { surf.color.Red = subChunkReader.ReadSingle(); surf.color.Green = subChunkReader.ReadSingle(); surf.color.Blue = subChunkReader.ReadSingle(); surf.color.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } case SurfaceParameter.ID_LUMI: surf.luminosity.Value = subChunkReader.ReadSingle(); surf.luminosity.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_DIFF: surf.diffuse.Value = subChunkReader.ReadSingle(); surf.diffuse.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_SPEC: surf.specularity.Value = subChunkReader.ReadSingle(); surf.specularity.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_GLOS: surf.glossiness.Value = subChunkReader.ReadSingle(); surf.glossiness.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_REFL: surf.reflection.values.Value = subChunkReader.ReadSingle(); surf.reflection.values.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_RFOP: surf.reflection.options = subChunkReader.ReadUInt16(); break; case SurfaceParameter.ID_RIMG: surf.reflection.clip_index = subChunkReader.ReadVariableLengthIndex(); break; // Reflection Blurring - RBLR { blur-percentage[FP4], envelope[VX] } // The amount of blurring of reflections. The default is zero. case SurfaceParameter.ID_RBLR: break; case SurfaceParameter.ID_RSAN: surf.reflection.seam_angle = subChunkReader.ReadSingle(); break; case SurfaceParameter.ID_TRAN: surf.transparency.values.Value = subChunkReader.ReadSingle(); surf.transparency.values.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_TROP: surf.transparency.options = subChunkReader.ReadUInt16(); break; case SurfaceParameter.ID_TIMG: surf.transparency.clip_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_RIND: surf.eta.Value = subChunkReader.ReadSingle(); surf.eta.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_TRNL: surf.translucency.Value = subChunkReader.ReadSingle(); surf.translucency.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_BUMP: surf.bump.Value = subChunkReader.ReadSingle(); surf.bump.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_SMAN: surf.smooth = subChunkReader.ReadSingle(); break; case SurfaceParameter.ID_SIDE: surf.sideflags = subChunkReader.ReadUInt16(); break; case SurfaceParameter.ID_CLRH: surf.color_hilite.value = subChunkReader.ReadSingle(); surf.color_hilite.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_CLRF: surf.color_filter.value = subChunkReader.ReadSingle(); surf.color_filter.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_ADTR: surf.add_trans.value = subChunkReader.ReadSingle(); surf.add_trans.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_SHRP: surf.dif_sharp.value = subChunkReader.ReadSingle(); surf.dif_sharp.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_GVAL: surf.glow.value = subChunkReader.ReadSingle(); surf.glow.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; // Render Outlines - LINE { flags[U2], ( size[F4], size-envelope[VX], ( color[COL12], color-envelope[VX] )? )? } case SurfaceParameter.ID_LINE: surf.line.enabled = 1; if (sz >= 2) surf.line.flags = subChunkReader.ReadUInt16(); if (sz >= 6) surf.line.size.value = subChunkReader.ReadSingle(); if (sz >= 8) surf.line.size.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; case SurfaceParameter.ID_ALPH: surf.alpha_mode = subChunkReader.ReadUInt16(); surf.alpha = subChunkReader.ReadSingle(); break; case SurfaceParameter.ID_AVAL: surf.alpha = subChunkReader.ReadSingle(); break; case SurfaceParameter.ID_BLOK: { var type = subChunkReader.ReadID<TextureType>(); switch (type) { case TextureType.ID_IMAP: case TextureType.ID_PROC: case TextureType.ID_GRAD: { using (var blockReader = subChunkReader.GetSubChunk((uint)subChunkReader.BytesLeft)) { var tex = Texture.ReadTexture(blockReader, type); switch ( tex.Channel ) { case TextureChannel.ID_COLR: surf.color .textures.Add(tex); break; case TextureChannel.ID_LUMI: surf.luminosity .textures.Add(tex); break; case TextureChannel.ID_DIFF: surf.diffuse .textures.Add(tex); break; case TextureChannel.ID_SPEC: surf.specularity .textures.Add(tex); break; case TextureChannel.ID_GLOS: surf.glossiness .textures.Add(tex); break; case TextureChannel.ID_REFL: surf.reflection .values .textures.Add(tex); break; case TextureChannel.ID_TRAN: surf.transparency .values .textures.Add(tex); break; case TextureChannel.ID_RIND: surf.eta .textures.Add(tex); break; case TextureChannel.ID_TRNL: surf.translucency .textures.Add(tex); break; case TextureChannel.ID_BUMP: surf.bump .textures.Add(tex); break; default: throw new Exception("Unknown texture channel"); // TODO: create proper exception calass for this } } break; } case TextureType.ID_SHDR: { using (var blockReader = subChunkReader.GetSubChunk((uint)subChunkReader.BytesLeft)) { surf.shader.Add( LightwavePlugin.ReadShader(blockReader) ); } break; } default: Console.WriteLine("Unknown blok type " + reader.GetIDString((uint)type)); break; } break; } default: Console.WriteLine("Unknown surface parameter type " + reader.GetIDString((uint)id)); break; } } } return surf; }
static IEnumerable<string> ReadTags(ChunkReader reader) { while (reader.BytesLeft > 0) yield return reader.ReadString(); }