private bool DetermineLayout(SceneView sceneView) { if (Event.current.type != EventType.Layout) { return(false); } Transform cameraTransform = sceneView.camera.transform; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); bool validSurface = false; bool hitSurface = Physics.Raycast(ray, out RaycastHit hit); if (hitSurface) { GameObject surfaceObject = hit.transform.gameObject; int surfaceLayer = surfaceObject.layer; int surfaceMask = 1 << surfaceLayer; validSurface = (SurfaceLayers.value & surfaceMask) == surfaceMask; } if (validSurface) { _lastHitTangentSpace = TangentSpace.CreateFromUp(hit.point, hit.normal, cameraTransform.up); UpdatePlacementLocations(); } else { _lastHitTangentSpace = null; } return(true); }
void OrbitalMovement() { Vector2 delta = Vector2.zero; // The view direction change also detects mouse panning if (!Input.GetButton("ChangeViewDirection")) { float horizontalOffset = CalculateEdgePanningIntensity(Input.mousePosition.x, Screen.width, horizontalEdgeZoneWidthEdgePanning); float verticalOffset = CalculateEdgePanningIntensity(Input.mousePosition.y, Screen.height, verticalEdgeZoneHeightEdgePanning); delta = Vector2.ClampMagnitude(new Vector2(horizontalOffset, verticalOffset), 1.0f) * orbitalMovementSensitivity * Time.deltaTime; } TangentSpace startingPositionTangentSpace = new TangentSpace(-(transform.localPosition).normalized); // These two values should stay constant after the transformation Vector3 tanGlazingAngle = startingPositionTangentSpace.Earth2Tan.MultiplyVector(transform.parent.InverseTransformVector(transform.forward)).normalized; Vector3 tanUp = startingPositionTangentSpace.Earth2Tan.MultiplyVector(transform.parent.InverseTransformVector(transform.up)).normalized; // Smoothly accelarates/decelerates to the target speed verticalSpeed = Mathf.SmoothDamp(verticalSpeed, (delta.y), ref verticalAccelaration, orbitalSmoothness); horizontalSpeed = Mathf.SmoothDamp(horizontalSpeed, (delta.x), ref horizontalAccelaration, orbitalSmoothness); // Rotate around the earth core, along the "right" and "up" of the screen/view space transform.RotateAround(transform.parent.position, transform.right, verticalSpeed); transform.RotateAround(transform.parent.position, -transform.up, horizontalSpeed); float polarAngle = Vector3.Angle(transform.localPosition, Vector3.up); float minPolarAngle = (90 - maxLatitude); float maxPolarAngle = (90 - minLatitude); // If the new position is too far in the north/south if (polarAngle <= minPolarAngle || polarAngle >= maxPolarAngle) { float theta = (polarAngle <= minPolarAngle ? minPolarAngle : maxPolarAngle) * Mathf.Deg2Rad; float orbitAltitude = transform.localPosition.magnitude; // The radius of the circle, intersected by the max/min latitude line float intersectionPlaneRadius = Mathf.Sin(theta) * orbitAltitude; // Project the camera position to the intersection plane Vector2 intersection = new Vector2(transform.localPosition.x, transform.localPosition.z); // Extend the intersection to find a new point along the circle Vector2 adjustedDestinationProjection = intersection.normalized * intersectionPlaneRadius; transform.localPosition = new Vector3(adjustedDestinationProjection.x, Mathf.Cos(theta) * orbitAltitude, adjustedDestinationProjection.y); } // Re-align the viewing directions TangentSpace destinationTangentSpace = new TangentSpace(-(transform.localPosition).normalized); transform.LookAt(transform.position + transform.parent.TransformVector(destinationTangentSpace.Tan2Earth.MultiplyVector(tanGlazingAngle)), transform.parent.TransformVector(destinationTangentSpace.Tan2Earth.MultiplyVector(tanUp))); }
private Vector3 GetGesternWave(WaveVO wave, ref TangentSpace tangentSpace, Vector3 p, float t) { float w = Mathf.Sqrt(9.81f * ((2f * Mathf.PI) / wave.wavelength)); //float w = 2 * UNITY_PI / wave.wavelength; float PHI_t = wave.speed * w * t; Vector2 D = wave.direction; D.Normalize(); float Q = wave.steepnes / (w * wave.amplitude * 2); float f1 = w * Vector2.Dot(D, new Vector2(p.x, p.z)) + PHI_t; float S = Mathf.Sin(f1); float C = Mathf.Cos(f1); float WA = w * wave.amplitude; float WAS = WA * S; float WAC = WA * C; tangentSpace.binormal += new Vector3 ( Q * (D.x * D.x) * WAS, D.x * WAC, Q * (D.x * D.y) * WAS ); tangentSpace.tangent += new Vector3 ( Q * (D.x * D.y) * WAS, D.y * WAC, Q * (D.y * D.y) * WAS ); tangentSpace.normal += new Vector3 ( D.x * WAC, Q * WAS, D.y * WAC ); float f3 = Mathf.Cos(f1); float f4 = Q * wave.amplitude * f3; return(new Vector3 ( f4 * D.x, // X wave.amplitude * Mathf.Sin(f1), // Y f4 * D.y // Z )); }
public Metric(FundamentalPoly poly, int xres, int yres) { space = new TangentSpace[xres, yres]; topology = poly; ll = topology.MinBound; ur = topology.MaxBound; for (int i = 0; i < xres; i++) { for (int j = 0; j < yres; j++) { float x = i / xres; float y = j / yres; space[i,j] = new TangentSpace(1,0,0,1); } } }
// Update is called once per frame void OnDrawGizmos() { WaveVO wave1 = new WaveVO(); wave1.wavelength = wavelength1; wave1.amplitude = amplitude1; wave1.speed = speed1; wave1.direction = direction1; wave1.steepnes = steepnes1; WaveVO wave2 = new WaveVO(); wave2.wavelength = wavelength2; wave2.amplitude = amplitude2; wave2.speed = speed2; wave2.direction = direction2; wave2.steepnes = steepnes2; for (float i = 0; i < 30; i++) { for (float j = 0; j < 30; j++) { Vector3 point = new Vector3(i, 0, j); TangentSpace tangentSpace = new TangentSpace(); point += GetGesternWave(wave1, ref tangentSpace, point, Time.time); point += GetGesternWave(wave2, ref tangentSpace, point, Time.time); Gizmos.color = Color.black; Gizmos.DrawSphere(point, 0.15f); Gizmos.color = Color.green; tangentSpace = calculateTangentSpace(tangentSpace); Matrix4x4 texSpace = new Matrix4x4(tangentSpace.binormal, tangentSpace.normal, tangentSpace.tangent, new Vector3()); Vector3 normal = new Vector3(0, 1, 0); Vector3 finalNormal = Vector3.Normalize(texSpace * normal); Gizmos.DrawLine(point, point + finalNormal); } } }
public static void DrawHandles(this TangentSpace space, Vector3 worldPosition, float scale = 1f, float width = 15f) { Color previousColor = Handles.color; CompareFunction previousZTest = Handles.zTest; try { Handles.zTest = CompareFunction.Always; const float arrowSize = .1f; DrawAxis(Handles.xAxisColor, width, worldPosition, space.Forward, scale, arrowSize); DrawAxis(Handles.zAxisColor, width, worldPosition, space.Left, scale, arrowSize); DrawAxis(Handles.yAxisColor, width, worldPosition, space.Up, scale, arrowSize); } finally { Handles.zTest = previousZTest; Handles.color = previousColor; } }
void TangentMovement() { TangentSpace tangentSpace = new TangentSpace(-(transform.localPosition).normalized); if (Input.GetButton("ChangeViewDirection")) { Cursor.lockState = CursorLockMode.Confined; Cursor.visible = false; // The altitude stays constant for this method. float currentAltitude = transform.localPosition.magnitude; float offsetX = CalculateEdgePanningIntensity(Input.mousePosition.x, Screen.width, horizontalEdgeZoneWidthTangentMovement); float offsetY = CalculateEdgePanningIntensity(Input.mousePosition.y, Screen.height, verticalEdgeZoneHeightTangentMovement); Vector3 offset = (new Vector3(offsetX, offsetY, 0)) * tanSensitivity * Time.deltaTime; newTanGlainzgAngle = (tanViewingDir + offset * Time.deltaTime).normalized; float angle = Vector3.Angle(Vector3.forward, newTanGlainzgAngle); float maxAngle = Mathf.Lerp(maxAngleDegAtLowAlt, maxAngleDegAtHighAlt, (currentAltitude - minAltitude) / (maxAltitude - minAltitude)); if (angle > maxAngle) { Vector3 rotationalAxis = Vector3.Cross(newTanGlainzgAngle, Vector3.forward).normalized; newTanGlainzgAngle = Quaternion.AngleAxis(angle - maxAngle, rotationalAxis) * newTanGlainzgAngle; } } else { newTanGlainzgAngle = Vector3.zero; Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } tanViewingDir = Vector3.SmoothDamp(tanViewingDir, newTanGlainzgAngle, ref tanVelocity, tanSmooth).normalized; // Aligning the up direction via the Gram–Schmidt process Vector3 tanUp = (Vector3.Dot(Vector3.up, tanViewingDir) * tanViewingDir + Vector3.up).normalized; transform.LookAt(transform.position + transform.parent.TransformVector(tangentSpace.Tan2Earth.MultiplyVector(tanViewingDir)), transform.parent.TransformVector(tangentSpace.Tan2Earth.MultiplyVector(tanUp))); }
TangentSpace calculateTangentSpace(TangentSpace tangentSpace) { tangentSpace.binormal = new Vector3( 1 - tangentSpace.binormal.x, tangentSpace.binormal.y, -tangentSpace.binormal.z ); tangentSpace.tangent = new Vector3( -tangentSpace.tangent.x, tangentSpace.tangent.y, 1 - tangentSpace.tangent.z ); tangentSpace.normal = new Vector3( -tangentSpace.normal.x, 1 - tangentSpace.normal.y, -tangentSpace.normal.z ); return(tangentSpace); }
public override void Write(AssetWriter writer) { base.Write(writer); if (HasLODData(writer.Version)) { LODData.Write(writer); } else { if (HasUse16bitIndices(writer.Version)) { writer.Write(Use16BitIndices); } if (IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } SubMeshes.Write(writer); } if (HasBlendShapes(writer.Version)) { if (HasBlendChannels(writer.Version)) { Shapes.Write(writer); } else { BlendShapes.Write(writer); writer.AlignStream(AlignType.Align4); ShapeVertices.Write(writer); } } if (HasBindPose(writer.Version)) { if (IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasBoneNameHashes(writer.Version)) { BoneNameHashes.Write(writer); writer.Write(RootBoneNameHash); } if (HasBonesAABB(writer.Version)) { BonesAABB.Write(writer); VariableBoneCountWeights.Write(writer); } if (HasMeshCompression(writer.Version)) { writer.Write((byte)MeshCompression); } if (HasStreamCompression(writer.Version)) { writer.Write(StreamCompression); } if (HasIsReadable(writer.Version)) { writer.Write(IsReadable); writer.Write(KeepVertices); writer.Write(KeepIndices); } if (IsAlignFlags(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasIndexFormat(writer.Version)) { if (IsIndexFormatCondition(writer.Version)) { if (MeshCompression == MeshCompression.Off) { writer.Write((int)IndexFormat); } } else { writer.Write((int)IndexFormat); } } if (!HasLODData(writer.Version)) { if (!IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } } if (HasVertexData(writer.Version)) { if (!IsOnlyVertexData(writer.Version)) { if (MeshCompression != MeshCompression.Off) { Vertices.Write(writer); } } } else { Vertices.Write(writer); } if (HasSkin(writer.Version)) { Skin.Write(writer); } if (HasBindPose(writer.Version)) { if (!IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasVertexData(writer.Version)) { if (IsOnlyVertexData(writer.Version)) { VertexData.Write(writer); } else { if (MeshCompression == MeshCompression.Off) { VertexData.Write(writer); } else { UV.Write(writer); UV1.Write(writer); Tangents.Write(writer); Normals.Write(writer); Colors.Write(writer); } } } else { UV.Write(writer); if (HasUV1(writer.Version)) { UV1.Write(writer); } if (HasTangentSpace(writer.Version)) { TangentSpace.Write(writer); } else { Tangents.Write(writer); Normals.Write(writer); } } if (IsAlignVertex(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasCompressedMesh(writer.Version)) { CompressedMesh.Write(writer); } LocalAABB.Write(writer); if (!HasVertexData(writer.Version)) { Colors.Write(writer); } if (HasCollisionTriangles(writer.Version)) { CollisionTriangles.Write(writer); writer.Write(CollisionVertexCount); } if (HasMeshUsageFlags(writer.Version)) { writer.Write(MeshUsageFlags); } if (HasCollision(writer.Version)) { CollisionData.Write(writer); } if (HasMeshMetrics(writer.Version)) { writer.Write(MeshMetrics[0]); writer.Write(MeshMetrics[1]); } #if UNIVERSAL if (HasMeshOptimization(writer.Version, writer.Flags)) { if (IsMeshOptimizationFlags(writer.Version)) { writer.Write((int)MeshOptimizationFlags); } else { writer.Write(MeshOptimized); } } #endif if (HasStreamData(writer.Version)) { writer.AlignStream(AlignType.Align4); StreamData.Write(writer); } }
private void modifyElem(TangentSpace mod, float amt, int i, int j) { Vector2 newAC = mod.transform(new Vector2(space[i, j].A, space[i, j].C)); Vector2 newBD = mod.transform(new Vector2(space[i, j].B, space[i, j].D)); space[i, j].A = (amt * newAC.X + (1 - amt) * space[i, j].A); space[i, j].B = (amt * newBD.X + (1 - amt) * space[i, j].B); space[i, j].C = (amt * newAC.Y + (1 - amt) * space[i, j].C); space[i, j].D = (amt * newBD.Y + (1 - amt) * space[i, j].D); }
public void modifyUniform(TangentSpace mod) { for (int i = 0; i < space.GetLength(0); i++) { for (int j = 0; j < space.GetLength(0); j++) { modifyElem(mod, 1, i, j); } } }
public void modifyCircle(TangentSpace mod, Vector2 center, float radius) { float dx = (ur.X - ll.X) / space.GetLength(0); float dy = (ur.Y - ll.Y) / space.GetLength(1); for (float x = center.X - radius; x < center.X + radius; x += dx) { for (float y = center.Y - radius; y < center.Y + radius; y += dy) { float dist = (center - new Vector2(x, y)).Length(); if (dist < radius) { int i, j; internalLookup(new Vector2(x, y), out i, out j); modifyElem(mod, (radius - dist) / radius, i, j); } } } }
public static void DrawHandles(this TangentSpace space, float scale = 1f, float width = 5f) { DrawHandles(space, space.ReferenceOrigin, scale, width); }