public static T Create <T>(string name, UnityEngine.Transform parent, Matrix4x4 trsMatrix) where T : ChiselNode { // TODO: put matrix4x4 -> transform values, into utility method var position = trsMatrix.GetColumn(3); trsMatrix.SetColumn(3, Vector4.zero); var columnX = trsMatrix.GetColumn(0); var columnY = trsMatrix.GetColumn(1); var columnZ = trsMatrix.GetColumn(2); var scaleX = columnX.magnitude; var scaleY = columnY.magnitude; var scaleZ = columnZ.magnitude; columnX /= scaleX; columnY /= scaleY; columnZ /= scaleZ; if (Vector3.Dot(Vector3.Cross(columnZ, columnY), columnX) > 0) { scaleX = -scaleX; columnX = -columnX; } var scale = new Vector3(scaleX, scaleY, scaleZ); var rotation = Quaternion.LookRotation(columnZ, columnY); //var inverseMatrix = Matrix4x4.TRS(position, rotation, scale).inverse * trsMatrix; //Debug.Log(position + " " + rotation + " " + scale + "\n" + inverseMatrix); return(Create <T>(name, parent, position, rotation, scale)); }
public static bool GeneratePathedStairs(ref ChiselBrushContainer brushContainer, ref ChiselPathedStairsDefinition definition) { definition.Validate(); var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); GetPathVertices(definition.shape, definition.curveSegments, shapeVertices, shapeSegmentIndices); var totalSubMeshCount = 0; for (int i = 0; i < shapeVertices.Count; i++) { if (i == 0 && !definition.shape.closed) { continue; } var leftSide = (!definition.shape.closed && i == 1) ? definition.stairs.leftSide : StairsSideType.None; var rightSide = (!definition.shape.closed && i == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None; totalSubMeshCount += BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide); } if (totalSubMeshCount == 0) { return(false); } // var stairDirections = definition.shape.closed ? shapeVertices.Count : (shapeVertices.Count - 1); brushContainer.EnsureSize(totalSubMeshCount); var depth = definition.stairs.depth; var height = definition.stairs.height; var halfDepth = depth * 0.5f; var halfHeight = height * 0.5f; int subMeshIndex = 0; for (int vi0 = shapeVertices.Count - 3, vi1 = shapeVertices.Count - 2, vi2 = shapeVertices.Count - 1, vi3 = 0; vi3 < shapeVertices.Count; vi0 = vi1, vi1 = vi2, vi2 = vi3, vi3++) { if (vi2 == 0 && !definition.shape.closed) { continue; } // TODO: optimize this, we're probably redoing a lot of stuff for every iteration var v0 = shapeVertices[vi0]; var v1 = shapeVertices[vi1]; var v2 = shapeVertices[vi2]; var v3 = shapeVertices[vi3]; var m0 = (v0 + v1) * 0.5f; var m1 = (v1 + v2) * 0.5f; var m2 = (v2 + v3) * 0.5f; var d0 = (v1 - v0); var d1 = (v2 - v1); var d2 = (v3 - v2); var maxWidth0 = d0.magnitude; var maxWidth1 = d1.magnitude; var maxWidth2 = d2.magnitude; var halfWidth1 = d1 * 0.5f; d0 /= maxWidth0; d1 /= maxWidth1; d2 /= maxWidth2; var depthVector = new Vector3(d1.y, 0, -d1.x); var lineCenter = new Vector3(m1.x, halfHeight, m1.y) - (depthVector * halfDepth); var depthVector0 = new Vector2(d0.y, -d0.x) * depth; var depthVector1 = new Vector2(d1.y, -d1.x) * depth; var depthVector2 = new Vector2(d2.y, -d2.x) * depth; m0 -= depthVector0; m1 -= depthVector1; m2 -= depthVector2; Vector2 output; var leftShear = Intersect(m1, d1, m0, d0, out output) ? Vector2.Dot(d1, (output - (m1 - halfWidth1))) : 0; var rightShear = Intersect(m1, d1, m2, d2, out output) ? -Vector2.Dot(d1, (output - (m1 + halfWidth1))) : 0; var transform = Matrix4x4.TRS(lineCenter, // move to center of line Quaternion.LookRotation(depthVector, Vector3.up), // rotate to align with line Vector3.one); // set the width to the width of the line definition.stairs.width = maxWidth1; definition.stairs.nosingWidth = 0; var leftSide = (!definition.shape.closed && vi2 == 1) ? definition.stairs.leftSide : StairsSideType.None; var rightSide = (!definition.shape.closed && vi2 == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None; var subMeshCount = BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide); if (subMeshCount == 0) { continue; } if (!BrushMeshFactory.GenerateLinearStairsSubMeshes(ref brushContainer, definition.stairs, leftSide, rightSide, subMeshIndex)) { return(false); } var halfWidth = maxWidth1 * 0.5f; for (int m = 0; m < subMeshCount; m++) { var vertices = brushContainer.brushMeshes[subMeshIndex + m].vertices; for (int v = 0; v < vertices.Length; v++) { // TODO: is it possible to put all of this in a single matrix? // lerp the stairs to go from less wide to wider depending on the depth of the vertex var depthFactor = 1.0f - ((vertices[v].z / definition.stairs.depth) + 0.5f); var wideFactor = (vertices[v].x / halfWidth) + 0.5f; var scale = (vertices[v].x / halfWidth); // lerp the stairs width depending on if it's on the left or right side of the stairs vertices[v].x = Mathf.Lerp(scale * (halfWidth - (rightShear * depthFactor)), scale * (halfWidth - (leftShear * depthFactor)), wideFactor); vertices[v] = transform.MultiplyPoint(vertices[v]); } } subMeshIndex += subMeshCount; } return(false); }
private CameraExtrinsics GetExtrinsics(SpatialCoordinateSystem frameCoordinateSystem) { if (frameCoordinateSystem == null) { return(null); } CameraExtrinsics extrinsics = null; if (rootCoordinateSystem == null) { return(null); } System.Numerics.Matrix4x4?worldMatrix = frameCoordinateSystem.TryGetTransformTo(rootCoordinateSystem); if (worldMatrix.HasValue) { WindowsVector3 position; WindowsVector3 scale; WindowsQuaternion rotation; WindowsMatrix4x4.Decompose(worldMatrix.Value, out scale, out rotation, out position); WindowsVector3 forward = WindowsVector3.Transform(-WindowsVector3.UnitZ, rotation); WindowsVector3 up = WindowsVector3.Transform(WindowsVector3.UnitY, rotation); Matrix4x4 unityWorldMatrix = Matrix4x4.TRS(WindowsVectorToUnityVector(position), Quaternion.LookRotation(WindowsVectorToUnityVector(forward), WindowsVectorToUnityVector(up)), Vector3.one); extrinsics = new CameraExtrinsics() { ViewFromWorld = unityWorldMatrix }; } return(extrinsics); }