public RenderItem(Material material, RenderPrimitive renderPrimitive, Matrix xnaMatrix, ShapeFlags flags) { Material = material; RenderPrimitive = renderPrimitive; XNAMatrix = xnaMatrix; Flags = flags; }
public RenderItem(Material material, RenderPrimitive renderPrimitive, ref Matrix xnaMatrix, ShapeFlags flags, object itemData = null) { Material = material; RenderPrimitive = renderPrimitive; XNAMatrix = xnaMatrix; Flags = flags; ItemData = itemData; }
protected int IAnimationMatrix = -1; // index of animation matrix /// <summary> /// Construct and initialize the class /// </summary> public TurntableShape(string path, IWorldPosition positionSource, ShapeFlags flags, Turntable turntable, double startingY) : base(path, positionSource, flags) { Turntable = turntable; Turntable.StartingY = (float)startingY; Turntable.TurntableFrameRate = SharedShape.Animations[0].FrameRate; animationKey = (Turntable.YAngle / (float)Math.PI * 1800.0f + 3600) % 3600.0f; for (var imatrix = 0; imatrix < SharedShape.Matrices.Length; ++imatrix) { if (SharedShape.MatrixNames[imatrix].ToLower() == turntable.Animations[0].ToLower()) { IAnimationMatrix = imatrix; break; } } if (viewer.Simulator.TRK.Route.DefaultTurntableSMS != null) { var soundPath = viewer.Simulator.RoutePath + @"\\sound\\" + viewer.Simulator.TRK.Route.DefaultTurntableSMS; try { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } catch { soundPath = viewer.Simulator.BasePath + @"\\sound\\" + viewer.Simulator.TRK.Route.DefaultTurntableSMS; try { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } catch (Exception error) { Trace.WriteLine(new FileLoadException(soundPath, error)); } } } for (var matrix = 0; matrix < SharedShape.Matrices.Length; ++matrix) { AnimateMatrix(matrix, animationKey); } MatrixExtension.Multiply(in XNAMatrices[IAnimationMatrix], in WorldPosition.XNAMatrix, out Matrix absAnimationMatrix); Turntable.ReInitTrainPositions(absAnimationMatrix); }
protected int IAnimationMatrix = -1; // index of animation matrix /// <summary> /// Construct and initialize the class /// </summary> public TransfertableShape(string path, IWorldPosition positionSource, ShapeFlags flags, Transfertable transfertable) : base(path, positionSource, flags) { Transfertable = transfertable; animationKey = (Transfertable.XPos - Transfertable.CenterOffset.X) / Transfertable.Width * SharedShape.Animations[0].FrameCount; for (var imatrix = 0; imatrix < SharedShape.Matrices.Length; ++imatrix) { if (SharedShape.MatrixNames[imatrix].ToLower() == transfertable.Animations[0].ToLower()) { IAnimationMatrix = imatrix; break; } } if (viewer.Simulator.TRK.Route.DefaultTurntableSMS != null) { var soundPath = viewer.Simulator.RoutePath + @"\\sound\\" + viewer.Simulator.TRK.Route.DefaultTurntableSMS; try { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } catch { soundPath = viewer.Simulator.BasePath + @"\\sound\\" + viewer.Simulator.TRK.Route.DefaultTurntableSMS; try { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } catch (Exception error) { Trace.WriteLine(new FileLoadException(soundPath, error)); } } } for (var matrix = 0; matrix < SharedShape.Matrices.Length; ++matrix) { AnimateMatrix(matrix, animationKey); } MatrixExtension.Multiply(in XNAMatrices[IAnimationMatrix], in WorldPosition.XNAMatrix, out Matrix absAnimationMatrix); Transfertable.ReInitTrainPositions(absAnimationMatrix); }
protected int IAnimationMatrix = -1; // index of animation matrix /// <summary> /// Construct and initialize the class /// </summary> public TurntableShape(string path, IWorldPosition positionSource, ShapeFlags flags, TurnTable turntable, double startingY) : base(path, positionSource, flags) { Turntable = turntable; //Turntable.StartingY = (float)startingY; Turntable.TurntableFrameRate = SharedShape.Animations[0].FrameRate; animationKey = (Turntable.YAngle / (float)Math.PI * 1800.0f + 3600) % 3600.0f; for (var imatrix = 0; imatrix < SharedShape.Matrices.Length; ++imatrix) { if (SharedShape.MatrixNames[imatrix].Equals(turntable.Animations[0], StringComparison.OrdinalIgnoreCase)) { IAnimationMatrix = imatrix; break; } } if (viewer.Simulator.Route.DefaultTurntableSMS != null) { string soundPath = viewer.Simulator.RouteFolder.SoundFile(viewer.Simulator.Route.DefaultTurntableSMS); if (File.Exists(soundPath)) { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } else if (File.Exists(soundPath = viewer.Simulator.RouteFolder.ContentFolder.SoundFile(viewer.Simulator.Route.DefaultTurntableSMS))) { Sound = new SoundSource(viewer, WorldPosition.WorldLocation, SoundEventSource.Turntable, soundPath); viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } else { Trace.WriteLine($"Turntable soundfile {soundPath} not found"); } } for (var matrix = 0; matrix < SharedShape.Matrices.Length; ++matrix) { AnimateMatrix(matrix, animationKey); } MatrixExtension.Multiply(in XNAMatrices[IAnimationMatrix], in WorldPosition.XNAMatrix, out Matrix absAnimationMatrix); Turntable.ReInitTrainPositions(absAnimationMatrix); }
public SignalShape(Viewer viewer, SignalObj mstsSignal, string path, WorldPosition position, ShapeFlags flags) : base(viewer, path, position, flags) { #if DEBUG_SIGNAL_SHAPES Console.WriteLine("{0} signal {1}:", Location.ToString(), mstsSignal.UID); UID = mstsSignal.UID; #endif var signalShape = Path.GetFileName(path).ToUpper(); if (!viewer.SIGCFG.SignalShapes.ContainsKey(signalShape)) { Trace.TraceWarning("{0} signal {1} has invalid shape {2}.", Location.ToString(), mstsSignal.UID, signalShape); return; } var mstsSignalShape = viewer.SIGCFG.SignalShapes[signalShape]; #if DEBUG_SIGNAL_SHAPES Console.WriteLine(" Shape={0} SubObjs={1,-2} {2}", Path.GetFileNameWithoutExtension(path).ToUpper(), mstsSignalShape.SignalSubObjs.Count, mstsSignalShape.Description); #endif // The matrix names are used as the sub-object names. The sub-object visibility comes from // mstsSignal.SignalSubObj, which is mapped to names through mstsSignalShape.SignalSubObjs. var visibleMatrixNames = new bool[SharedShape.MatrixNames.Count]; for (var i = 0; i < mstsSignalShape.SignalSubObjs.Count; i++) { if ((((mstsSignal.SignalSubObj >> i) & 0x1) == 1) && (SharedShape.MatrixNames.Contains(mstsSignalShape.SignalSubObjs[i].MatrixName))) { visibleMatrixNames[SharedShape.MatrixNames.IndexOf(mstsSignalShape.SignalSubObjs[i].MatrixName)] = true; } } // All sub-objects except the one pointing to the first matrix (99.00% times it is the first one, but not always, see Protrain) are hidden by default. //For each other sub-object, look up its name in the hierarchy and use the visibility of that matrix. visibleMatrixNames[0] = true; SubObjVisible = new bool[SharedShape.LodControls[0].DistanceLevels[0].SubObjects.Length]; SubObjVisible[0] = true; for (var i = 1; i < SharedShape.LodControls[0].DistanceLevels[0].SubObjects.Length; i++) { if (i == SharedShape.RootSubObjectIndex) { SubObjVisible[i] = true; } else { var subObj = SharedShape.LodControls[0].DistanceLevels[0].SubObjects[i]; int minHiLevIndex = 0; if (subObj.ShapePrimitives[0].Hierarchy[subObj.ShapePrimitives[0].HierarchyIndex] > 0) // Search for ShapePrimitive with lowest Hierarchy Value and check visibility with it { var minHiLev = 999; for (var j = 0; j < subObj.ShapePrimitives.Length; j++) { if (subObj.ShapePrimitives[0].Hierarchy[subObj.ShapePrimitives[j].HierarchyIndex] < minHiLev) { minHiLevIndex = j; minHiLev = subObj.ShapePrimitives[0].Hierarchy[subObj.ShapePrimitives[j].HierarchyIndex]; } } } SubObjVisible[i] = visibleMatrixNames[SharedShape.LodControls[0].DistanceLevels[0].SubObjects[i].ShapePrimitives[minHiLevIndex].HierarchyIndex]; } } #if DEBUG_SIGNAL_SHAPES for (var i = 0; i < mstsSignalShape.SignalSubObjs.Count; i++) { Console.WriteLine(" SUBOBJ {1,-12} {0,-7} {2,3} {3,3} {4,2} {5,2} {6,-14} {8} ({7})", ((mstsSignal.SignalSubObj >> i) & 0x1) != 0 ? "VISIBLE" : "hidden", mstsSignalShape.SignalSubObjs[i].MatrixName, mstsSignalShape.SignalSubObjs[i].Optional ? "Opt" : "", mstsSignalShape.SignalSubObjs[i].Default ? "Def" : "", mstsSignalShape.SignalSubObjs[i].JunctionLink ? "JL" : "", mstsSignalShape.SignalSubObjs[i].BackFacing ? "BF" : "", mstsSignalShape.SignalSubObjs[i].SignalSubType == -1 ? "<none>" : MSTS.SignalShape.SignalSubObj.SignalSubTypes[mstsSignalShape.SignalSubObjs[i].SignalSubType], mstsSignalShape.SignalSubObjs[i].SignalSubSignalType, mstsSignalShape.SignalSubObjs[i].Description); } for (var i = 0; i < SubObjVisible.Length; i++) { Console.WriteLine(" SUBOBJ {0,-2} {1,-7}", i, SubObjVisible[i] ? "VISIBLE" : "hidden"); } #endif if (mstsSignal.SignalUnits == null) { Trace.TraceWarning("{0} signal {1} has no SignalUnits.", Location.ToString(), mstsSignal.UID); return; } for (var i = 0; i < mstsSignal.SignalUnits.Units.Length; i++) { #if DEBUG_SIGNAL_SHAPES Console.Write(" UNIT {0}: TrItem={1,-5} SubObj={2,-2}", i, mstsSignal.SignalUnits.Units[i].TrItem, mstsSignal.SignalUnits.Units[i].SubObj); #endif // Find the simulation SignalObject for this shape. var signalAndHead = viewer.Simulator.Signals.FindByTrItem(mstsSignal.SignalUnits.Units[i].TrItem); if (!signalAndHead.HasValue) { Trace.TraceWarning("Skipped {0} signal {1} unit {2} with invalid TrItem {3}", Location.ToString(), mstsSignal.UID, i, mstsSignal.SignalUnits.Units[i].TrItem); continue; } // Get the signal sub-object for this unit (head). var mstsSignalSubObj = mstsSignalShape.SignalSubObjs[mstsSignal.SignalUnits.Units[i].SubObj]; if (mstsSignalSubObj.SignalSubType != 1) // SIGNAL_HEAD { Trace.TraceWarning("Skipped {0} signal {1} unit {2} with invalid SubObj {3}", Location.ToString(), mstsSignal.UID, i, mstsSignal.SignalUnits.Units[i].SubObj); continue; } var mstsSignalItem = (SignalItem)(viewer.Simulator.TDB.TrackDB.TrItemTable[mstsSignal.SignalUnits.Units[i].TrItem]); try { // Go create the shape head. Heads.Add(new SignalShapeHead(viewer, this, i, signalAndHead.Value.Value, mstsSignalItem, mstsSignalSubObj)); } catch (InvalidDataException error) { Trace.TraceWarning(error.Message); } #if DEBUG_SIGNAL_SHAPES Console.WriteLine(); #endif } }
void AddShadowPrimitive(int shadowMapIndex, Material material, RenderPrimitive primitive, ref Matrix xnaMatrix, ShapeFlags flags) { if (material is SceneryMaterial) { RenderShadowSceneryItems[shadowMapIndex].Add(new RenderItem(material, primitive, ref xnaMatrix, flags)); } else if (material is ForestMaterial) { RenderShadowForestItems[shadowMapIndex].Add(new RenderItem(material, primitive, ref xnaMatrix, flags)); } else if (material is TerrainMaterial) { RenderShadowTerrainItems[shadowMapIndex].Add(new RenderItem(material, primitive, ref xnaMatrix, flags)); } else { Debug.Fail("Only scenery, forest and terrain materials allowed in shadow map."); } }
public void AddPrimitive(Material material, RenderPrimitive primitive, RenderPrimitiveGroup group, ref Matrix xnaMatrix, ShapeFlags flags, object itemData) { var getBlending = material.GetBlending(); var blending = getBlending && material is SceneryMaterial ? PrimitiveBlendedScenery : getBlending ? PrimitiveBlended : PrimitiveNotBlended; RenderItemCollection items; foreach (var blended in blending) { var sortingMaterial = blended ? DummyBlendedMaterial : material; var sequence = RenderItems[(int)GetRenderSequence(group, blended)]; if (!sequence.TryGetValue(sortingMaterial, out items)) { items = new RenderItemCollection(); sequence.Add(sortingMaterial, items); } items.Add(new RenderItem(material, primitive, ref xnaMatrix, flags, itemData)); } if (((flags & ShapeFlags.AutoZBias) != 0) && (primitive.ZBias == 0)) { primitive.ZBias = 1; } }
public void AddPrimitive(Material material, RenderPrimitive primitive, RenderPrimitiveGroup group, ref Matrix xnaMatrix, ShapeFlags flags) { AddPrimitive(material, primitive, group, ref xnaMatrix, flags, null); }
public void AddAutoPrimitive(Vector3 mstsLocation, float objectRadius, float objectViewingDistance, Material material, RenderPrimitive primitive, RenderPrimitiveGroup group, ref Matrix xnaMatrix, ShapeFlags flags) { if (float.IsPositiveInfinity(objectViewingDistance) || (Camera != null && Camera.InRange(mstsLocation, objectRadius, objectViewingDistance))) { if (Camera != null && Camera.InFov(mstsLocation, objectRadius)) { AddPrimitive(material, primitive, group, ref xnaMatrix, flags); } } if (Game.Settings.DynamicShadows && (RenderProcess.ShadowMapCount > 0) && ((flags & ShapeFlags.ShadowCaster) != 0)) { for (var shadowMapIndex = 0; shadowMapIndex < RenderProcess.ShadowMapCount; shadowMapIndex++) { if (IsInShadowMap(shadowMapIndex, mstsLocation, objectRadius, objectViewingDistance)) { AddShadowPrimitive(shadowMapIndex, material, primitive, ref xnaMatrix, flags); } } } }
public SeparateDataShape(EndianBinaryReader er) { Type = er.ReadUInt32(); Signature = er.ReadString(Encoding.ASCII, 4); if (Signature != "SOBJ") throw new SignatureNotCorrectException(Signature, "SOBJ", er.BaseStream.Position); Revision = er.ReadUInt32(); NameOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32(); Unknown2 = er.ReadUInt32(); Unknown3 = er.ReadUInt32(); Flags = (ShapeFlags)er.ReadUInt32(); OrientedBoundingBoxOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32(); PositionOffset = er.ReadVector3(); NrPrimitiveSets = er.ReadUInt32(); PrimitiveSetOffsetsArrayOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32(); BaseAddress = er.ReadUInt32(); NrVertexAttributes = er.ReadUInt32(); VertexAttributeOffsetsArrayOffset = (UInt32)er.BaseStream.Position + er.ReadUInt32(); BlendShapeOffset = er.ReadUInt32(); if (BlendShapeOffset != 0) BlendShapeOffset += (UInt32)er.BaseStream.Position - 4; long curpos = er.BaseStream.Position; er.BaseStream.Position = NameOffset; Name = er.ReadStringNT(Encoding.ASCII); er.BaseStream.Position = OrientedBoundingBoxOffset; BoundingBox = BoundingVolume.FromStream(er); er.BaseStream.Position = PrimitiveSetOffsetsArrayOffset; PrimitiveSetOffsets = new uint[NrPrimitiveSets]; for (int i = 0; i < NrPrimitiveSets; i++) { PrimitiveSetOffsets[i] = (UInt32)er.BaseStream.Position + er.ReadUInt32(); } er.BaseStream.Position = VertexAttributeOffsetsArrayOffset; VertexAttributeOffsets = new uint[NrVertexAttributes]; for (int i = 0; i < NrVertexAttributes; i++) { VertexAttributeOffsets[i] = (UInt32)er.BaseStream.Position + er.ReadUInt32(); } PrimitiveSets = new PrimitiveSet[NrPrimitiveSets]; for (int i = 0; i < NrPrimitiveSets; i++) { er.BaseStream.Position = PrimitiveSetOffsets[i]; PrimitiveSets[i] = new PrimitiveSet(er); } VertexAttributes = new VertexAttributeCtr[NrVertexAttributes]; if (NrVertexAttributes != 0) { for (int i = 0; i < NrVertexAttributes; i++) { er.BaseStream.Position = VertexAttributeOffsets[i]; VertexAttributes[i] = VertexAttributeCtr.FromStream(er); } } if (BlendShapeOffset != 0) { er.BaseStream.Position = BlendShapeOffset; BlendShape = new BlendShapeCtr(er); } er.BaseStream.Position = curpos; }
protected BaseShape(string path, ShapeFlags flags) { SharedShape = viewer.ShapeManager.Get(path); Flags = flags; }