public static Envelope ReadEnvelope(ChunkReader reader) { var env = new Envelope(); // allocate the Envelope structure env.Index = reader.ReadVariableLengthIndex(); // index EnvelopeKey lastKey = null; while (reader.BytesLeft > 0) { // process subchunks as they're encountered var id = reader.ReadID<EnvelopeType>(); var sz = reader.ReadUInt16(); sz += (ushort)(sz & 1); using (var subChunkReader = reader.GetSubChunk(sz)) { switch (id) { case EnvelopeType.ID_TYPE: { env.Type = subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_NAME: { env.Name = subChunkReader.ReadString(); break; } case EnvelopeType.ID_PRE: { env.PreBehavior = (EvalType)subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_POST: { env.PostBehavior = (EvalType)subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_KEY: { lastKey = new EnvelopeKey( subChunkReader.ReadSingle(), // time subChunkReader.ReadSingle() // value ); env.Keys.Add(lastKey); //TODO: not sort all the time env.Keys.Sort((Comparison<EnvelopeKey>)delegate(EnvelopeKey k1, EnvelopeKey k2) { return k1.Time > k2.Time ? 1 : k1.Time < k2.Time ? -1 : 0; }); break; } case EnvelopeType.ID_SPAN: { if (lastKey == null) // We should've encountered an ID_KEY before an ID_SPAN throw new Exception("Key not defined"); //TODO: make proper exception class lastKey.Shape = subChunkReader.ReadID<KeyShape>(); switch (lastKey.Shape) { case KeyShape.ID_TCB: { lastKey.Tension = subChunkReader.ReadSingle(); lastKey.Continuity = subChunkReader.ReadSingle(); lastKey.Bias = subChunkReader.ReadSingle(); break; } case KeyShape.ID_BEZI: case KeyShape.ID_HERM: case KeyShape.ID_BEZ2: { Array.Clear(lastKey.param, 0, lastKey.param.Length); int i = 0; while (i < 4 && subChunkReader.BytesLeft > 0) { lastKey.param[i] = subChunkReader.ReadSingle(); i++; } break; } case KeyShape.ID_LINE: break; default: Console.WriteLine("Unknown envelope span shape type " + reader.GetIDString((uint)lastKey.Shape)); break; } break; } case EnvelopeType.ID_CHAN: { var plug = new LightwavePlugin(); plug.name = subChunkReader.ReadString(); plug.flags = subChunkReader.ReadUInt16(); plug.data = subChunkReader.ReadBytes((uint)reader.BytesLeft); env.ChannelFilters.Add(plug); break; } default: Console.WriteLine("Unknown envelope type " + reader.GetIDString((uint)id)); break; } } } return env; }
// 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 Clip ReadClip(ChunkReader reader) { // index var index = reader.ReadUInt32(); // first subchunk header var type = reader.ReadID<ClipType>(); var subchunk_size = reader.ReadUInt16(); subchunk_size += (ushort)(subchunk_size & 1); Clip clip = null; using (var subChunkReader = reader.GetSubChunk(subchunk_size)) { switch (type) { case ClipType.ID_STIL: { var tmp_clip = new ClipStill(index); tmp_clip.Name = subChunkReader.ReadString(); clip = tmp_clip; break; } case ClipType.ID_ISEQ: { var tmp_clip = new ClipSequence(index); tmp_clip.Digits = subChunkReader.ReadUInt8(); tmp_clip.Flags = subChunkReader.ReadUInt8(); tmp_clip.Offset = subChunkReader.ReadSInt16(); subChunkReader.ReadUInt16(); // Legacy Cruft: Nothing to see here tmp_clip.Start = subChunkReader.ReadSInt16(); tmp_clip.End = subChunkReader.ReadSInt16(); tmp_clip.Prefix = subChunkReader.ReadString(); tmp_clip.Suffix = subChunkReader.ReadString(); clip = tmp_clip; break; } case ClipType.ID_ANIM: { var tmp_clip = new ClipAnim(index); tmp_clip.Name = subChunkReader.ReadString(); tmp_clip.Server = subChunkReader.ReadString(); tmp_clip.Data = subChunkReader.ReadBytes((uint)subChunkReader.BytesLeft); clip = tmp_clip; break; } case ClipType.ID_XREF: { var tmp_clip = new ClipCloned(index); tmp_clip.clip_reference_index = subChunkReader.ReadUInt32(); tmp_clip.Name = subChunkReader.ReadString(); clip = tmp_clip; break; } case ClipType.ID_STCC: { var tmp_clip = new ClipColorCycle(index); tmp_clip.lo = subChunkReader.ReadSInt16(); tmp_clip.hi = subChunkReader.ReadSInt16(); tmp_clip.Name = subChunkReader.ReadString(); clip = tmp_clip; break; } default: throw new Exception("Unknown Clip type"); // TODO: create proper exception class for this ... } } while (reader.BytesLeft > 0) { // process subchunks as they're encountered var id = reader.ReadID<ClipDataType>(); subchunk_size = reader.ReadUInt16(); subchunk_size += (ushort)(subchunk_size & 1); using (var subChunkReader = reader.GetSubChunk(subchunk_size)) { switch (id) { //case ClipDataType.ID_CLRS: // Color Space RGB - CLRS { flags[U2], colorspace[U2], filename[FNAM0] } //case ClipDataType.ID_CLRA: // Color Space Alpha - CLRA { flags[U2], colorspace[U2], filename[FNAM0] } //case ClipDataType.ID_FILT: // Image Filtering - FILT { flags[U2] } //case ClipDataType.ID_DITH: // Image Dithering - DITH { flags[U2] } // Contrast - CONT { contrast-delta[FP4], envelope[VX] } case ClipDataType.ID_CONT: { clip.Contrast.value = subChunkReader.ReadSingle(); clip.Contrast.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } // Brightness - BRIT { brightness-delta[FP4], envelope[VX] } case ClipDataType.ID_BRIT: { clip.Brightness.value = subChunkReader.ReadSingle(); clip.Brightness.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } // Saturation - SATR { saturation-delta[FP4], envelope[VX] } case ClipDataType.ID_SATR: { clip.Saturation.value = subChunkReader.ReadSingle(); clip.Saturation.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } // Hue - HUE { hue-rotation[FP4], envelope[VX] } case ClipDataType.ID_HUE: { clip.Hue.value = subChunkReader.ReadSingle(); clip.Hue.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } // Gamma Correction - GAMM { gamma[F4], envelope[VX] } case ClipDataType.ID_GAMM: { clip.Gamma.value = subChunkReader.ReadSingle(); clip.Gamma.envelope_index = subChunkReader.ReadVariableLengthIndex(); break; } // Negative - NEGA { enable[U2] } case ClipDataType.ID_NEGA: { clip.Negative = subChunkReader.ReadUInt16() != 0; break; } // Time - TIME { start-time[FP4], duration[FP4], frame-rate[FP4] } case ClipDataType.ID_TIME: { clip.StartTime = subChunkReader.ReadSingle(); clip.Duration = subChunkReader.ReadSingle(); clip.FrameRate = subChunkReader.ReadSingle(); break; } // Plug-in Image Filters - IFLT { server-name[S0], flags[U2], data[...] } case ClipDataType.ID_IFLT: // Plug-in Pixel Filters - PFLT { server-name[S0], flags[U2], data[...] } case ClipDataType.ID_PFLT: { var filt = new LightwavePlugin(); filt.name = subChunkReader.ReadString(); filt.flags = subChunkReader.ReadUInt16(); filt.data = subChunkReader.ReadBytes((uint)subChunkReader.BytesLeft); if (id == ClipDataType.ID_IFLT) clip.ImageFilters.Add(filt); else clip.PixelFilters.Add(filt); break; } case ClipDataType.ID_FLAG: // not mentioned in documentation ... var flags = subChunkReader.ReadUInt16(); // unknown what they mean ... break; default: Console.WriteLine("Unknown clip type " + reader.GetIDString((uint)id)); break; } } } return clip; }
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; }