public static Guides[] GetGuideIndex(GroupIdMapping groupIdMapping) { var stencils = WidgetManager.m_Instance.StencilWidgets.Where(s => s.gameObject.activeSelf).ToList(); if (stencils.Count == 0) { return(null); } Dictionary <StencilType, List <Guides.State> > guides = new Dictionary <StencilType, List <Guides.State> >(); foreach (var stencil in stencils) { if (!guides.ContainsKey(stencil.Type)) { guides[stencil.Type] = new List <Guides.State>(); } guides[stencil.Type].Add(stencil.GetSaveState(groupIdMapping)); } List <Guides> guideIndex = new List <Guides>(); foreach (var elem in guides) { guideIndex.Add(new Guides { Type = elem.Key, States = elem.Value.OrderBy(s => ByTranslation(s.Transform)).ToArray() }); } return(guideIndex.OrderBy(g => g.Type).ToArray()); }
/// Data that is saved to the .tilt file. /// Be very careful when changing this, because it affects the save file format. /// This does not really need to be virtual, except to implement the temporary /// backwards-compatibility code. public Guides.State GetSaveState(GroupIdMapping groupIdMapping) { return(new Guides.State { Transform = TrTransform.TRS(transform.localPosition, transform.localRotation, 0), Extents = Extents, Pinned = m_Pinned, GroupId = groupIdMapping.GetId(Group) }); }
public static TiltModels75[] GetTiltModels(GroupIdMapping groupIdMapping) { var widgets = WidgetManager.m_Instance.ModelWidgets.Where(w => w.gameObject.activeSelf).ToArray(); if (widgets.Length == 0 && !ModelCatalog.m_Instance.MissingModels.Any()) { return(null); } var widgetModels = widgets.Select(w => w.Model).Distinct(); Dictionary <Model.Location, List <WidgetMetadata> > modelLocationMap = new Dictionary <Model.Location, List <WidgetMetadata> >(); foreach (var model in widgetModels) { modelLocationMap[model.GetLocation()] = new List <WidgetMetadata>(); } foreach (var widget in widgets) { WidgetMetadata newEntry = new WidgetMetadata(); newEntry.xf = widget.GetSaveTransform(); newEntry.pinned = widget.Pinned; newEntry.groupId = groupIdMapping.GetId(widget.Group); modelLocationMap[widget.Model.GetLocation()].Add(newEntry); } List <TiltModels75> models = new List <TiltModels75>(); foreach (var elem in modelLocationMap) { var val = new TiltModels75 { Location = elem.Key, }; // Order and align the metadata. WidgetMetadata[] ordered = elem.Value.OrderBy(ByTranslation).ToArray(); val.PinStates = new bool[ordered.Length]; val.RawTransforms = new TrTransform[ordered.Length]; val.GroupIds = new uint[ordered.Length]; for (int i = 0; i < ordered.Length; ++i) { val.PinStates[i] = ordered[i].pinned; val.RawTransforms[i] = ordered[i].xf; val.GroupIds[i] = ordered[i].groupId; } models.Add(val); } return(models .Concat(ModelCatalog.m_Instance.MissingModels) .OrderBy(ByModelLocation).ToArray()); }
public static TiltVideo[] GetTiltVideos(GroupIdMapping groupIdMapping) { return(WidgetManager.m_Instance.VideoWidgets.Where(x => x.gameObject.activeSelf).Select(x => ConvertVideoToTiltVideo(x)).ToArray()); TiltVideo ConvertVideoToTiltVideo(VideoWidget widget) { TiltVideo video = new TiltVideo { FilePath = widget.Video.PersistentPath, AspectRatio = widget.Video.Aspect, Pinned = widget.Pinned, Transform = widget.SaveTransform, GroupId = groupIdMapping.GetId(widget.Group), }; if (widget.VideoController != null) { video.Paused = !widget.VideoController.Playing; video.Time = widget.VideoController.Time; video.Volume = widget.VideoController.Volume; } return(video); } }
/// Write out sketch memory strokes ordered by initial control point timestamp. /// Leaves stream in indeterminate state; caller should Close() upon return. /// Output brushList provides mapping from .sketch brush index to GUID. /// While writing out the strokes we adjust the stroke flags to take into account the effect /// of inactive items on grouping. public static void WriteMemory(Stream stream, IList <AdjustedMemoryBrushStroke> strokeCopies, GroupIdMapping groupIdMapping, out List <Guid> brushList) { bool allowFastPath = BitConverter.IsLittleEndian; var writer = new TiltBrush.SketchBinaryWriter(stream); writer.UInt32(SKETCH_SENTINEL); writer.Int32(SKETCH_VERSION); writer.Int32(0); // reserved for header: must be 0 // Bump SKETCH_VERSION to >= 6 and remove this comment if non-zero data is written here writer.UInt32(0); // additional data size var brushMap = new Dictionary <Guid, int>(); // map from GUID to index brushList = new List <Guid>(); // GUID's by index // strokes writer.Int32(strokeCopies.Count); foreach (var copy in strokeCopies) { var stroke = copy.strokeData; int brushIndex; Guid brushGuid = stroke.m_BrushGuid; if (!brushMap.TryGetValue(brushGuid, out brushIndex)) { brushIndex = brushList.Count; brushMap[brushGuid] = brushIndex; brushList.Add(brushGuid); } writer.Int32(brushIndex); writer.Color(stroke.m_Color); writer.Float(stroke.m_BrushSize); // Bump SKETCH_VERSION to >= 6 and remove this comment if any // length-prefixed stroke extensions are added StrokeExtension strokeExtensionMask = StrokeExtension.Flags | StrokeExtension.Seed; if (stroke.m_BrushScale != 1) { strokeExtensionMask |= StrokeExtension.Scale; } if (stroke.m_Group != SketchGroupTag.None) { strokeExtensionMask |= StrokeExtension.Group; } writer.UInt32((uint)strokeExtensionMask); uint controlPointExtensionMask = (uint)(ControlPointExtension.Pressure | ControlPointExtension.Timestamp); writer.UInt32(controlPointExtensionMask); // Stroke extension fields, in order of appearance in the mask writer.UInt32((uint)copy.adjustedStrokeFlags); if ((uint)(strokeExtensionMask & StrokeExtension.Scale) != 0) { writer.Float(stroke.m_BrushScale); } if ((uint)(strokeExtensionMask & StrokeExtension.Group) != 0) { writer.UInt32(groupIdMapping.GetId(stroke.m_Group)); } if ((uint)(strokeExtensionMask & StrokeExtension.Seed) != 0) { writer.Int32(stroke.m_Seed); } // Control points writer.Int32(stroke.m_ControlPoints.Length); if (allowFastPath && controlPointExtensionMask == ControlPoint.EXTENSIONS) { // Fast path: write ControlPoint[] (semi-)directly into the file unsafe { int size = sizeof(ControlPoint) * stroke.m_ControlPoints.Length; fixed(ControlPoint *aPoints = stroke.m_ControlPoints) { writer.Write((IntPtr)aPoints, size); } } } else { for (int j = 0; j < stroke.m_ControlPoints.Length; ++j) { var rControlPoint = stroke.m_ControlPoints[j]; writer.Vec3(rControlPoint.m_Pos); writer.Quaternion(rControlPoint.m_Orient); // Control point extension fields, in order of appearance in the mask writer.Float(rControlPoint.m_Pressure); writer.UInt32(rControlPoint.m_TimestampMs); } } } }
public static TiltImages75[] GetTiltImages(GroupIdMapping groupIdMapping) { var imports = WidgetManager.m_Instance.ImageWidgets .Where(w => w.gameObject.activeSelf).ToArray(); if (imports.Length == 0) { return(null); } // From the list of image widgets in the sketch, create a map that contains a unique // entry per image, with associated metadata (transform and pin state) stored as arrays. Dictionary <string, List <WidgetMetadata> > imagesByFileName = new Dictionary <string, List <WidgetMetadata> >(); Dictionary <string, float> aspectRatios = new Dictionary <string, float>(); foreach (var image in imports) { string fileName = image.FileName; if (image.AspectRatio == null) { Debug.LogError("Trying to save partially-initialized image {fileName}"); } if (!imagesByFileName.ContainsKey(fileName)) { imagesByFileName[fileName] = new List <WidgetMetadata>(); aspectRatios[fileName] = image.AspectRatio ?? 1; } WidgetMetadata newEntry = new WidgetMetadata(); newEntry.xf = image.SaveTransform; newEntry.pinned = image.Pinned; newEntry.tinted = image.UseLegacyTint; newEntry.groupId = groupIdMapping.GetId(image.Group); imagesByFileName[fileName].Add(newEntry); } // Build the save metadata from our unique map. List <TiltImages75> imageIndex = new List <TiltImages75>(); foreach (var elem in imagesByFileName) { var val = new TiltImages75 { FileName = elem.Key, AspectRatio = aspectRatios[elem.Key] }; // Order and align the metadata. WidgetMetadata[] ordered = elem.Value.OrderBy(ByTranslation).ToArray(); val.PinStates = new bool[ordered.Length]; val.TintStates = new bool[ordered.Length]; val.Transforms = new TrTransform[ordered.Length]; val.GroupIds = new uint[ordered.Length]; for (int i = 0; i < ordered.Length; ++i) { val.PinStates[i] = ordered[i].pinned; val.TintStates[i] = ordered[i].tinted; val.Transforms[i] = ordered[i].xf; val.GroupIds[i] = ordered[i].groupId; } imageIndex.Add(val); } return(imageIndex.OrderBy(i => i.FileName).ToArray()); }