float CalculatePushback(OffsetData offset, Vector3 idealCenterPoint, CameraBumper.BumperDirection validDirections = CameraBumper.BumperDirection.AllDirections) { RaycastHit hitInfo; var pushbackDueToCollision = 0f; if (Physics.Raycast(idealCenterPoint + offset.StartPointRelativeToCamera, offset.NormalizedVector, out hitInfo, offset.DistanceFromStartPoint, cameraBumperLayers)) { var bumper = hitInfo.collider.GetComponent <CameraBumper>(); if (null == bumper || (bumper != null && (bumper.blockDirection & validDirections) != CameraBumper.BumperDirection.None)) { pushbackDueToCollision = offset.DistanceFromStartPoint - hitInfo.distance; #if UNITY_EDITOR if (drawDebugLines) { Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + (offset.NormalizedVector * hitInfo.distance), Color.red); } #endif } } #if UNITY_EDITOR else if (drawDebugLines) { Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + offset.Vector, Color.green); } #endif return(pushbackDueToCollision); }
private float CalculatePushback(OffsetData offset, Vector3 idealCenterPoint, BumperDirection validDirections = BumperDirection.AllDirections) { RaycastHit hitInfo; float pushbackDueToCollision = 0f; if (Physics.Raycast(idealCenterPoint + offset.StartPointRelativeToCamera, offset.NormalizedVector, out hitInfo, offset.DistanceFromStartPoint, cameraBumperLayers)) { pushbackDueToCollision = offset.DistanceFromStartPoint - hitInfo.distance; #if UNITY_EDITOR if (drawDebugLines) { Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + (offset.NormalizedVector * hitInfo.distance), Color.red); } #endif } #if UNITY_EDITOR else if (drawDebugLines) { Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + offset.Vector, Color.green); } #endif return(pushbackDueToCollision); }
public override void WriteDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; if (FileHeader != null) { ele.TryPathTo("FileHeader", true, out subEle); FileHeader.WriteXML(subEle, master); } if (OffsetData != null) { ele.TryPathTo("OffsetData", true, out subEle); OffsetData.WriteXML(subEle, master); } if (DeletionsData != null) { ele.TryPathTo("DeletionsData", true, out subEle); DeletionsData.WriteXML(subEle, master); } if (Author != null) { ele.TryPathTo("Author", true, out subEle); Author.WriteXML(subEle, master); } if (Description != null) { ele.TryPathTo("Description", true, out subEle); Description.WriteXML(subEle, master); } if (MasterFiles != null) { ele.TryPathTo("MasterFiles", true, out subEle); List <string> xmlNames = new List <string> { "MasterFile" }; int i = 0; foreach (var entry in MasterFiles) { i = i % xmlNames.Count(); XElement newEle = new XElement(xmlNames[i]); entry.WriteXML(newEle, master); subEle.Add(newEle); i++; } } if (OverriddenRecords != null) { ele.TryPathTo("OverriddenRecords", true, out subEle); OverriddenRecords.WriteXML(subEle, master); } if (ScreenshotData != null) { ele.TryPathTo("ScreenshotData", true, out subEle); ScreenshotData.WriteXML(subEle, master); } }
/// <summary> /// This calculates the points to be used when determining collision with CameraBumper objects. /// Typically this only needs to be run once, but if the DistanceMultiplier is changed this /// will need to be run before the next collision with a CameraBumper. /// </summary> public void CalculateScreenBounds() { Func <Vector3, Vector3, OffsetData> AddRaycastOffsetPoint = (viewSpaceOrigin, viewSpacePoint) => { if (cameraToUse.orthographic) { Vector3 origin = cameraToUse.ViewportToWorldPoint(viewSpaceOrigin); Vector3 vectorToOffset = cameraToUse.ViewportToWorldPoint(viewSpacePoint) - origin; return(new OffsetData { StartPointRelativeToCamera = origin - transform.position, Vector = vectorToOffset, NormalizedVector = vectorToOffset.normalized, DistanceFromStartPoint = vectorToOffset.magnitude }); } else { Vector3 cameraPositionOnPlane = transform.position + (transform.forward * heightFromTarget); Ray originRay = cameraToUse.ViewportPointToRay(viewSpaceOrigin); float theta = Vector3.Angle(transform.forward, originRay.direction); float distanceToPlane = heightFromTarget / Mathf.Cos(theta * Mathf.Deg2Rad); Vector3 originPointOnPlane = originRay.origin + (originRay.direction * distanceToPlane); Ray pointRay = cameraToUse.ViewportPointToRay(viewSpacePoint); theta = Vector3.Angle(cameraToUse.transform.forward, pointRay.direction); distanceToPlane = heightFromTarget / Mathf.Cos(theta * Mathf.Deg2Rad); Vector3 pointOnPlane = pointRay.origin + (pointRay.direction * distanceToPlane); Vector3 vectorToOffset = pointOnPlane - originPointOnPlane; return(new OffsetData { StartPointRelativeToCamera = originPointOnPlane - cameraPositionOnPlane, Vector = vectorToOffset, NormalizedVector = vectorToOffset.normalized, DistanceFromStartPoint = vectorToOffset.magnitude }); } }; leftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0, 0.5f)); rightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(1, 0.5f)); lowerLeftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0), new Vector3(0, 0)); lowerRightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0), new Vector3(1, 0)); upperLeftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 1), new Vector3(0, 1)); upperRightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 1), new Vector3(1, 1)); downRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0.5f, 0)); upRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0.5f, 1)); leftUpRaycastPoint = AddRaycastOffsetPoint(new Vector3(0, 0.5f), new Vector3(0, 1)); leftDownRaycastPoint = AddRaycastOffsetPoint(new Vector3(0, 0.5f), new Vector3(0, 0)); rightUpRaycastPoint = AddRaycastOffsetPoint(new Vector3(1, 0.5f), new Vector3(1, 1)); rightDownRaycastPoint = AddRaycastOffsetPoint(new Vector3(1, 0.5f), new Vector3(1, 0)); }
partial void WriteOffsetData(ESPWriter writer) { if (OffsetDataSize == null) { OffsetData.WriteBinary(writer); } else { writer.Write(Utility.DesanitizeTag(OffsetData.Tag).ToCharArray()); writer.Write((ushort)0); writer.Write(OffsetData.Value); } }
public override void WriteData(ESPWriter writer) { if (FileHeader != null) { FileHeader.WriteBinary(writer); } if (OffsetData != null) { OffsetData.WriteBinary(writer); } if (DeletionsData != null) { DeletionsData.WriteBinary(writer); } if (Author != null) { Author.WriteBinary(writer); } if (Description != null) { Description.WriteBinary(writer); } if (MasterFiles != null) { foreach (var item in MasterFiles) { item.WriteBinary(writer); } } if (OverriddenRecords != null) { OverriddenRecords.WriteBinary(writer); } if (ScreenshotData != null) { ScreenshotData.WriteBinary(writer); } }
/** * @brief bvh 로딩 함수. * @param string file bvh파일 경로. * @return 성공시 true, 실패시 false 반환. */ public bool LoadBvhData(string file) { Clear(); if (!File.Exists(file)) { return(false); } string[] arrLine = File.ReadAllLines(file); m_BvhPath = file; int i = 0; int flag = 0; OffsetData tmpData = new OffsetData(); bool initChannel = false; int flagCount = 0; m_ChanaelCount = 0; //offset Data while (i < arrLine.Length) { string line = arrLine[i]; string[] lines = line.Split(new[] { " ", "\t" }, System.StringSplitOptions.RemoveEmptyEntries); if (line.Contains("JOINT")) { tmpData.name = lines[1]; } else if (line.Contains("End") || line.Contains("ROOT")) { tmpData.name = lines[1]; } else if (line.Contains("OFFSET")) { int j = 0; for (j = 0; j < lines.Length; j++) { if (lines[j] == "OFFSET") { break; } } float x = (float)System.Convert.ToDouble(lines[j + 1]); float y = (float)System.Convert.ToDouble(lines[j + 2]); float z = (float)System.Convert.ToDouble(lines[j + 3]); tmpData.offset = new Vector3(x, y, z); tmpData.flag = flag; m_OffsetDatas.Add(tmpData); flagCount++; if (tmpData.name.Contains("Site") || tmpData.name.Contains("Hips")) { flag++; //int tmpFlag = new int(); //tmpFlag = flagCount; //print(tmpFlag); m_FlagCount.Add(flagCount); flagCount = 0; } } else if (line.Contains("CHANNELS")) { m_ChanaelCount++; if (!initChannel) { string[] channels = line.Split(new[] { " ", "\t" }, System.StringSplitOptions.RemoveEmptyEntries); int num = channels.Length; int minus = num - 3; for (int j = 0; j < num; j++) { if (channels[j].Contains("Xrotation")) { m_IndexX = j - minus; } else if (channels[j].Contains("Yrotation")) { m_IndexY = j - minus; } else if (channels[j].Contains("Zrotation")) { m_IndexZ = j - minus; } } initChannel = true; } } else if (line.Contains("MOTION")) { break; } i++; } List <Vector3[]> rotationOrder = new List <Vector3[]>(); m_JointController.SetOffsetData(m_OffsetDatas, m_FlagCount); for (int j = 0; j < m_JointController.m_Joints.Count; j++) { Vector3[] tmpVec = new Vector3[3]; Transform tmpTrans = m_JointController.m_Joints[j]; if (tmpTrans != null) { tmpVec[m_IndexX] = Vector3.right; tmpVec[m_IndexY] = Vector3.up; tmpVec[m_IndexZ] = Vector3.forward; rotationOrder.Add(tmpVec); } else { rotationOrder.Add(null); } } //frame Data while (i < arrLine.Length) { i++; string line = arrLine[i]; if (line.Contains("Frames")) { string[] lines = line.Split(new[] { ":" }, System.StringSplitOptions.RemoveEmptyEntries); m_TotalFrames = System.Convert.ToInt32(lines[1]); print("Frames : " + m_TotalFrames); } else if (line.Contains("Frame Time")) { string[] lines = line.Split(new[] { ":" }, System.StringSplitOptions.RemoveEmptyEntries); m_FrameTime = (float)System.Convert.ToDouble(lines[1]); i++; print("FrameTime : " + m_FrameTime); break; } } //motion data while (i < arrLine.Length) { string line = arrLine[i]; if (line == "") { continue; } string[] lines = line.Split(new[] { ' ', '\t' }, System.StringSplitOptions.RemoveEmptyEntries); float px, py, pz; float.TryParse(lines[0], out px); float.TryParse(lines[1], out py); float.TryParse(lines[2], out pz); Vector3 pos = new Vector3(-px, py, pz); m_PositionData.Add(pos); Quaternion[] arrQuatFromEulerAngle = new Quaternion[m_ChanaelCount]; Vector3[] arrQuatFromEulerAngleV = new Vector3[m_ChanaelCount]; for (int j = 3; j < lines.Length; j += 3) // 0~2번째는 hip의 position데이터 { if (lines[j] == "") { continue; } int index = (j / 3) - 1; float[] rot = new float[3]; float.TryParse(lines[j], out rot[0]); //-178 z float.TryParse(lines[j + 1], out rot[1]); //47 y float.TryParse(lines[j + 2], out rot[2]); //179 Vector3 v = new Vector3(rot[m_IndexX], rot[m_IndexY], rot[m_IndexZ]); Quaternion q = new Quaternion(); if (rotationOrder[index] != null) { //right hand -> left hand rot[m_IndexZ] = -rot[m_IndexZ]; rot[m_IndexY] = -rot[m_IndexY]; q = Quaternion.AngleAxis(rot[0], rotationOrder[index][0]) //z * Quaternion.AngleAxis(rot[1], rotationOrder[index][1]) //y * Quaternion.AngleAxis(rot[2], rotationOrder[index][2]); //x } arrQuatFromEulerAngle[index] = q; arrQuatFromEulerAngleV[index] = v; } m_LocalQuatData.Add(arrQuatFromEulerAngle); m_RotationDataV.Add(arrQuatFromEulerAngleV); i++; } rotationOrder.Clear(); m_JointController.SetHipsHeight(m_PositionData[0].y); m_DataInit = true; return(true); }
float CalculatePushback(OffsetData offset, Vector3 idealCenterPoint, CameraBumper.BumperDirection validDirections = CameraBumper.BumperDirection.AllDirections) { RaycastHit hitInfo; var pushbackDueToCollision = 0f; if(Physics.Raycast(idealCenterPoint + offset.StartPointRelativeToCamera, offset.NormalizedVector, out hitInfo, offset.DistanceFromStartPoint, cameraBumperLayers)) { var bumper = hitInfo.collider.GetComponent<CameraBumper>(); if(null == bumper || (bumper != null && (bumper.blockDirection & validDirections) != CameraBumper.BumperDirection.None)) { pushbackDueToCollision = offset.DistanceFromStartPoint - hitInfo.distance; #if UNITY_EDITOR if(drawDebugLines) Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + (offset.NormalizedVector * hitInfo.distance), Color.red); #endif } } #if UNITY_EDITOR else if(drawDebugLines) Debug.DrawLine(idealCenterPoint + offset.StartPointRelativeToCamera, idealCenterPoint + offset.StartPointRelativeToCamera + offset.Vector, Color.green); #endif return pushbackDueToCollision; }
/// <summary> /// This calculates the points to be used when determining collision with CameraBumper objects. /// Typically this only needs to be run once, but if the DistanceMultiplier is changed this /// will need to be run before the next collision with a CameraBumper. /// </summary> public void CalculateScreenBounds() { System.Func<Vector3, Vector3, OffsetData> AddRaycastOffsetPoint = (viewSpaceOrigin, viewSpacePoint) => { if(camera.isOrthoGraphic) { var origin = camera.ViewportToWorldPoint(viewSpaceOrigin); var vectorToOffset = camera.ViewportToWorldPoint(viewSpacePoint) - origin; return new OffsetData { StartPointRelativeToCamera = origin - transform.position, Vector = vectorToOffset, NormalizedVector = vectorToOffset.normalized, DistanceFromStartPoint = vectorToOffset.magnitude }; } else { var cameraPositionOnPlane = transform.position + (transform.forward * heightFromTarget); var originRay = camera.ViewportPointToRay(viewSpaceOrigin); var theta = Vector3.Angle(transform.forward, originRay.direction); var distanceToPlane = heightFromTarget / Mathf.Cos(theta * Mathf.Deg2Rad); var originPointOnPlane = originRay.origin + (originRay.direction * distanceToPlane); var pointRay = camera.ViewportPointToRay(viewSpacePoint); theta = Vector3.Angle(camera.transform.forward, pointRay.direction); distanceToPlane = heightFromTarget / Mathf.Cos(theta * Mathf.Deg2Rad); var pointOnPlane = pointRay.origin + (pointRay.direction * distanceToPlane); var vectorToOffset = pointOnPlane - originPointOnPlane; return new OffsetData { StartPointRelativeToCamera = originPointOnPlane - cameraPositionOnPlane, Vector = vectorToOffset, NormalizedVector = vectorToOffset.normalized, DistanceFromStartPoint = vectorToOffset.magnitude }; } }; leftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0, 0.5f)); rightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(1, 0.5f)); lowerLeftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0), new Vector3(0, 0)); lowerRightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0), new Vector3(1, 0)); upperLeftRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 1), new Vector3(0, 1)); upperRightRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 1), new Vector3(1, 1)); downRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0.5f, 0)); upRaycastPoint = AddRaycastOffsetPoint(new Vector3(0.5f, 0.5f), new Vector3(0.5f, 1)); leftUpRaycastPoint = AddRaycastOffsetPoint(new Vector3(0, 0.5f), new Vector3(0, 1)); leftDownRaycastPoint = AddRaycastOffsetPoint(new Vector3(0, 0.5f), new Vector3(0, 0)); rightUpRaycastPoint = AddRaycastOffsetPoint(new Vector3(1, 0.5f), new Vector3(1, 1)); rightDownRaycastPoint = AddRaycastOffsetPoint(new Vector3(1, 0.5f), new Vector3(1, 0)); }
/// <summary> /// Updates the currently displayed frames when the projectile frame delay is changed. /// </summary> private void UpdateDisplayedFrames() { // Are any DRS files loaded? Are there drawable frames? if (_drs1 == null && _drs2 == null || _drawnImages.Count == 0) { return; } // Ensure frame delay is in range int frameDelay = CurrentUnitEntry.Value.ProjectileFrameDelay % _currentUnitGraphic.FrameCount; // Generate and assign frames for (short a = 0; a < _drawnImages.Count; ++a) { // Get frame ID int frameId = frameDelay + a * _currentUnitGraphic.FrameCount; // Calculate combined frame dimensions while setting the anchor point to (0, 0) OffsetData frameDimensions = new OffsetData(0, 0, 0, 0); // Store considered SLPs for later drawing // Tuple: frameId, anchorX, anchorY, slpObject // slpObject == null --> redraw main SLP var drawnSlpFrames = new List <Tuple <int, int, int, SLPFile> >(); // Check primary SLP SLPFile primarySlp = null; SLPFile.FrameInformationHeader primarySlpFrameHeader = null; if (_currentUnitGraphic.SLP >= 0 && _slps.ContainsKey((ushort)_currentUnitGraphic.SLP)) { // Get SLP primarySlp = _slps[(ushort)_currentUnitGraphic.SLP]; // Update dimensions primarySlpFrameHeader = primarySlp._frameInformationHeaders[frameId]; frameDimensions.Left = primarySlpFrameHeader.AnchorX; frameDimensions.Top = primarySlpFrameHeader.AnchorY; frameDimensions.Right = (int)primarySlpFrameHeader.Width - primarySlpFrameHeader.AnchorX; frameDimensions.Bottom = (int)primarySlpFrameHeader.Height - primarySlpFrameHeader.AnchorY; // Add SLP to render list // Only if no deltas are present, else the primary graphic should be drawn explicitly if (_renderedDeltas.Count == 0) { drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(frameId, primarySlpFrameHeader.AnchorX, primarySlpFrameHeader.AnchorY, primarySlp)); } } // Check deltas foreach (var currDelta in _renderedDeltas) { // Redrawer? if (currDelta.GraphicID == -1 && primarySlp != null) { drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(frameId, primarySlpFrameHeader.AnchorX, primarySlpFrameHeader.AnchorY, primarySlp)); } else if (currDelta.GraphicID != -1) { // Get graphic and SLP var currDeltaGraphic = _genieFile.Graphics[currDelta.GraphicID]; SLPFile currDeltaSlp = _slps[(ushort)currDeltaGraphic.SLP]; // Update dimensions int currDeltaFrameId = GetCorrespondingFrameId(frameId, _currentUnitGraphic, currDeltaGraphic); SLPFile.FrameInformationHeader frameHeader = currDeltaSlp._frameInformationHeaders[currDeltaFrameId]; frameDimensions.Left = Math.Max(frameDimensions.Left, frameHeader.AnchorX + currDelta.DirectionX); frameDimensions.Top = Math.Max(frameDimensions.Top, frameHeader.AnchorY + currDelta.DirectionY); frameDimensions.Right = Math.Max(frameDimensions.Right, (int)frameHeader.Width - (frameHeader.AnchorX + currDelta.DirectionX)); frameDimensions.Bottom = Math.Max(frameDimensions.Bottom, (int)frameHeader.Height - (frameHeader.AnchorY + currDelta.DirectionY)); // Add delta SLP to render list drawnSlpFrames.Add(new Tuple <int, int, int, SLPFile>(currDeltaFrameId, frameHeader.AnchorX + currDelta.DirectionX, frameHeader.AnchorY + currDelta.DirectionY, currDeltaSlp)); } } // Render frame if neccessary if (!_precomputedUnitFrames.ContainsKey(frameId)) { // Fall back to empty image if there are no graphics to be drawn if (drawnSlpFrames.Count == 0) { _precomputedUnitFrames[frameId] = new System.Drawing.Bitmap(1, 1).ToImageSource(); } else { // Create bitmap // 'using' environment to free memory correctly, avoiding OutOfMemory exceptions using (System.Drawing.Bitmap currFrame = new System.Drawing.Bitmap(frameDimensions.Left + frameDimensions.Right, frameDimensions.Top + frameDimensions.Bottom)) { // Draw on bitmap using (System.Drawing.Graphics currFrameG = System.Drawing.Graphics.FromImage(currFrame)) { // Get main frame System.Drawing.Bitmap primarySlpFrame = (primarySlpFrameHeader == null ? null : primarySlp.getFrameAsBitmap((uint)frameId, Pal50500, SLPFile.Masks.Graphic, System.Drawing.Color.FromArgb(0, 0, 0, 0), System.Drawing.Color.FromArgb(100, 100, 100, 100)) ); // Go through render list and render main image and deltas foreach (Tuple <int, int, int, SLPFile> currRenderEntry in drawnSlpFrames) { // Draw main frame? if (currRenderEntry.Item4 == primarySlp) { // Ensure that main frame exists if (primarySlpFrame != null) { currFrameG.DrawImage(primarySlpFrame, frameDimensions.Left - primarySlpFrameHeader.AnchorX, frameDimensions.Top - primarySlpFrameHeader.AnchorY); } } else { // Draw delta frame currFrameG.DrawImage(currRenderEntry.Item4.getFrameAsBitmap((uint)currRenderEntry.Item1, Pal50500, SLPFile.Masks.Graphic, System.Drawing.Color.FromArgb(0, 0, 0, 0), System.Drawing.Color.FromArgb(100, 100, 100, 100)), frameDimensions.Left - currRenderEntry.Item2, frameDimensions.Top - currRenderEntry.Item3); } } } _precomputedUnitFrames[frameId] = currFrame.ToImageSource(); } } } // Assign to drawn image objects _drawnImages[a].Source = _precomputedUnitFrames[frameId]; _drawnImages[a].Width = _precomputedUnitFrames[frameId].Width; _drawnImages[a].Height = _precomputedUnitFrames[frameId].Height; _anchors[a] = new Point(frameDimensions.Left, frameDimensions.Top); // Frame anchor point // Calculate bounds including the anchor point _maxFrameOffsets.Left = Math.Max(_maxFrameOffsets.Left, frameDimensions.Left); _maxFrameOffsets.Right = Math.Max(_maxFrameOffsets.Right, frameDimensions.Right); _maxFrameOffsets.Top = Math.Max(_maxFrameOffsets.Top, frameDimensions.Top); _maxFrameOffsets.Bottom = Math.Max(_maxFrameOffsets.Bottom, frameDimensions.Bottom); } // Update positions UpdatePositions(); }
/// <summary> /// Updates the render panel when a new unit is loaded. /// </summary> private void UpdateUnitRenderData() { // Are any DRS files loaded? if (_drs1 == null && _drs2 == null || _genieFile == null) { return; } // If no unit is given or the unit does not have projectile data, clear panel if (CurrentUnitEntry.Key < 0 || CurrentUnitEntry.Value?.ProjectileCount == null) { // Clear and abort _renderPanel.Children.Clear(); return; } // Clear lists _renderPanel.Children.Clear(); _renderedDeltas.Clear(); _drawnImages.Clear(); _precomputedUnitFrames.Clear(); _slps.Clear(); _anchors.Clear(); _anchorPointShapes.Clear(); _projectileAreaShapes.Clear(); // Reset frame offsets _maxFrameOffsets = new OffsetData(0, 0, 0, 0); // Find unit data // There must be at least one civ where this unit is defined, else the BalancingFile class would consist only of null members foreach (Civ c in _genieFile.Civs) { if (c.UnitPointers[CurrentUnitEntry.Key] > 0) { // Unit is defined, use data _currentUnitData = c.Units[CurrentUnitEntry.Key]; break; } } // Find graphic if (_currentUnitData.Type50?.AttackGraphic >= 0 && _genieFile.GraphicPointers[_currentUnitData.Type50.AttackGraphic] > 0) { _currentUnitGraphic = _genieFile.Graphics[_currentUnitData.Type50.AttackGraphic]; } else if (_currentUnitData.StandingGraphic1 >= 0 && _genieFile.GraphicPointers[_currentUnitData.StandingGraphic1] > 0) { _currentUnitGraphic = _genieFile.Graphics[_currentUnitData.StandingGraphic1]; } else { // Abort, no graphic available _currentUnitGraphic = null; return; } // Find deltas; use only deltas that have graphic ID -1 or an existing SLP foreach (var currDelta in _currentUnitGraphic.Deltas) { if (currDelta.GraphicID == -1 || (currDelta.GraphicID >= 0 && _genieFile.GraphicPointers[currDelta.GraphicID] > 0 && ((_drs1?.ResourceExists((uint)_genieFile.Graphics[currDelta.GraphicID].SLP) ?? false) || (_drs2?.ResourceExists((uint)_genieFile.Graphics[currDelta.GraphicID].SLP) ?? false)))) { _renderedDeltas.Add(currDelta); } } // Load needed SLPs Action <ushort> loadSlpFromDrs = (slpId) => { // Get SLP from DRS by priority if (_slps.ContainsKey(slpId)) { return; } if (_drs1?.ResourceExists(slpId) ?? false) { _slps[slpId] = new SLPFile(new RAMBuffer(_drs1.GetResourceData(slpId))); } else if (_drs2?.ResourceExists(slpId) ?? false) { _slps[slpId] = new SLPFile(new RAMBuffer(_drs2.GetResourceData(slpId))); } }; if (_currentUnitGraphic.SLP >= 0) { loadSlpFromDrs((ushort)_currentUnitGraphic.SLP); } foreach (var currDelta in _renderedDeltas) { if (currDelta.GraphicID >= 0) { loadSlpFromDrs((ushort)_genieFile.Graphics[currDelta.GraphicID].SLP); } } // Create shape objects depending on angle count (ignore mirrored sides) // Each shape gets an event handler for mouse events, such that it can be dragged around by the user int effectiveAngleCount = (_currentUnitGraphic.MirroringMode > 0 ? _currentUnitGraphic.AngleCount / 2 + 1 : _currentUnitGraphic.AngleCount); for (int a = 0; a < effectiveAngleCount; ++a) { // Create image Image img = new Image { Tag = a }; img.MouseLeftButtonDown += _shape_OnMouseLeftButtonDown; img.MouseLeftButtonUp += _shape_OnMouseLeftButtonUp; _drawnImages.Add(img); _renderPanel.Children.Add(img); // Create anchor point list items _anchors.Add(new Point()); // Create anchor point shape Ellipse anchorEllipse = new Ellipse { Fill = Brushes.Magenta, Width = 3, Height = 3, Tag = a }; anchorEllipse.MouseLeftButtonDown += _shape_OnMouseLeftButtonDown; anchorEllipse.MouseLeftButtonUp += _shape_OnMouseLeftButtonUp; _anchorPointShapes.Add(anchorEllipse); _renderPanel.Children.Add(anchorEllipse); // Create projectile area shape Rectangle projectileRectangle = new Rectangle { Fill = new SolidColorBrush(ProjectileAreaTransparentColor), Width = TileSideLength, Height = TileSideLength, Tag = a }; projectileRectangle.MouseLeftButtonDown += _shape_OnMouseLeftButtonDown; projectileRectangle.MouseLeftButtonUp += _shape_OnMouseLeftButtonUp; projectileRectangle.RenderTransform = new RotateTransform(a * 45, projectileRectangle.Width / 2, projectileRectangle.Height / 2); _projectileAreaShapes.Add(projectileRectangle); _renderPanel.Children.Add(projectileRectangle); } // Initialize user defined offsets while (_userDefinedFrameOffsets.Count < effectiveAngleCount) { _userDefinedFrameOffsets.Add(new Point()); } // Show initial frame UpdateDisplayedFrames(); }
public override void ReadData(ESPReader reader, long dataEnd) { while (reader.BaseStream.Position < dataEnd) { string subTag = reader.PeekTag(); switch (subTag) { case "HEDR": if (FileHeader == null) { FileHeader = new PluginHeader(); } FileHeader.ReadBinary(reader); break; case "OFST": if (OffsetData == null) { OffsetData = new SimpleSubrecord <Byte[]>(); } OffsetData.ReadBinary(reader); break; case "DELE": if (DeletionsData == null) { DeletionsData = new SimpleSubrecord <Byte[]>(); } DeletionsData.ReadBinary(reader); break; case "CNAM": if (Author == null) { Author = new SimpleSubrecord <String>(); } Author.ReadBinary(reader); break; case "SNAM": if (Description == null) { Description = new SimpleSubrecord <String>(); } Description.ReadBinary(reader); break; case "MAST": if (MasterFiles == null) { MasterFiles = new List <MasterFileData>(); } MasterFileData tempMAST = new MasterFileData(); tempMAST.ReadBinary(reader); MasterFiles.Add(tempMAST); break; case "ONAM": if (OverriddenRecords == null) { OverriddenRecords = new FormArray(); } OverriddenRecords.ReadBinary(reader); break; case "SCRN": if (ScreenshotData == null) { ScreenshotData = new SimpleSubrecord <Byte[]>(); } ScreenshotData.ReadBinary(reader); break; default: throw new Exception(); } } }
public override void ReadDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; if (ele.TryPathTo("FileHeader", false, out subEle)) { if (FileHeader == null) { FileHeader = new PluginHeader(); } FileHeader.ReadXML(subEle, master); } if (ele.TryPathTo("OffsetData", false, out subEle)) { if (OffsetData == null) { OffsetData = new SimpleSubrecord <Byte[]>(); } OffsetData.ReadXML(subEle, master); } if (ele.TryPathTo("DeletionsData", false, out subEle)) { if (DeletionsData == null) { DeletionsData = new SimpleSubrecord <Byte[]>(); } DeletionsData.ReadXML(subEle, master); } if (ele.TryPathTo("Author", false, out subEle)) { if (Author == null) { Author = new SimpleSubrecord <String>(); } Author.ReadXML(subEle, master); } if (ele.TryPathTo("Description", false, out subEle)) { if (Description == null) { Description = new SimpleSubrecord <String>(); } Description.ReadXML(subEle, master); } if (ele.TryPathTo("MasterFiles", false, out subEle)) { if (MasterFiles == null) { MasterFiles = new List <MasterFileData>(); } foreach (XElement e in subEle.Elements()) { MasterFileData tempMAST = new MasterFileData(); tempMAST.ReadXML(e, master); MasterFiles.Add(tempMAST); } } if (ele.TryPathTo("OverriddenRecords", false, out subEle)) { if (OverriddenRecords == null) { OverriddenRecords = new FormArray(); } OverriddenRecords.ReadXML(subEle, master); } if (ele.TryPathTo("ScreenshotData", false, out subEle)) { if (ScreenshotData == null) { ScreenshotData = new SimpleSubrecord <Byte[]>(); } ScreenshotData.ReadXML(subEle, master); } }