/// <summary>Scales a size to fit inside the grid.</summary> /// <returns>The re-scaled vector.</returns> /// <param name="scl">The vector to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// /// Scales a size to the nearest multiple of the grid’s spacing. The /// parameter *ignoreAxis* makes the function not touch the corresponding /// coordinate. public override Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis) { //Vector3 relScale = scl.GFModulo3(spacing); var relScale = new Vector3(scl.x % spacing.x, scl.y % spacing.y, scl.z % spacing.z); var newScale = Vector3.zero; for (int i = 0; i <= 2; i++) { newScale[i] = scl[i]; if (relScale[i] >= 0.5f * spacing[i]) { newScale[i] = newScale[i] - relScale[i] + spacing[i]; } else { newScale[i] = newScale[i] - relScale[i]; //if we went too far default to the spacing if (newScale[i] < spacing[i]) { newScale[i] = spacing[i]; } } } for (int i = 0; i < 3; i++) { if (ignoreAxis[i]) { newScale[i] = scl[i]; } } return(newScale); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { BoolVector3 objectProperty = (BoolVector3)fieldInfo.GetValue(property.serializedObject.targetObject); EditorGUI.BeginProperty(position, label, property); // Inline child fields. var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); // Create the toggles and their labels. int toggleIndex = 0; GUIStyle style = GUI.skin.label; style.alignment = TextAnchor.MiddleCenter; objectProperty.x = EditorGUI.Toggle(GetToggleRect(position, toggleIndex), objectProperty.x); EditorGUI.LabelField(GetLabelRect(position, toggleIndex), "X", style); toggleIndex++; objectProperty.y = EditorGUI.Toggle(GetToggleRect(position, toggleIndex), objectProperty.y); EditorGUI.LabelField(GetLabelRect(position, toggleIndex), "Y", style); toggleIndex++; objectProperty.z = EditorGUI.Toggle(GetToggleRect(position, toggleIndex), objectProperty.z); EditorGUI.LabelField(GetLabelRect(position, toggleIndex), "Z", style); // Set indent back to what it was. EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); }
/// <summary>Scales a size vector to fit inside a grid.</summary> /// <param name="scl">The vector to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// <returns>The re-scaled vector.</returns> /// /// Scales a given scale vector to the nearest multiple of the grid’s /// radius and depth, but does not change its position. The parameter /// <paramref name="ignoreAxis"/> makes the function not touch the /// corresponding coordinate. public override Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis) { Vector3 result = Vector3.Max(RoundMultiple(scl[idx[0]], radius) * locUnits[idx[0]] + scl[idx[1]] * locUnits[idx[1]] + RoundMultiple(scl[idx[2]], depth) * locUnits[idx[2]], radius * locUnits[idx[0]] + scl[idx[1]] * locUnits[idx[1]] + depth * locUnits[idx[2]]); for (int i = 0; i <= 2; i++) { result[i] = ignoreAxis[i] ? scl[i] : result[i]; } return(result); }
/// <summary>Fits a Transform inside the grid (without scaling it).</summary> /// <param name="theTransform">The Transform to align.</param> /// <param name="rotate">Whether to rotate to the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// /// Fits an object inside the grid by using the object’s Transform. Setting <c>doRotate</c> makes the object take on the grid’s rotation. The parameter <c>lockAxis</c> /// makes the function not touch the corresponding coordinate. /// /// The resulting position depends on <paramref name="AlignVector3"/>, so please look up how that method works. public void AlignTransform(Transform theTransform, bool rotate, BoolVector3 ignoreAxis) { Quaternion oldRotation = theTransform.rotation; theTransform.rotation = transform.rotation; theTransform.position = AlignVector3(theTransform.position, theTransform.lossyScale, ignoreAxis); if (!rotate) { theTransform.rotation = oldRotation; } }
/// <summary>Fits a position vector into the grid.</summary> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the poistion into the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// <returns>Aligned position vector.</returns> /// /// Fits a position inside the grid by using the object’s transform. /// Currently the object will snap either on edges or between, depending on /// which is closer, ignoring the <paramref name="scale"/> passed, but I /// might add an option for this in the future. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis) { float fracAngle = World2Angle(pos) / angle - Mathf.Floor(World2Angle(pos) / angle); float fracRad = World2Radius(pos) / radius - Mathf.Floor(World2Radius(pos) / radius); Vector3 vertex = NearestVertexP(pos); Vector3 box = NearestBoxP(pos); Vector3 final = Vector3.zero; final += (0.25f < fracRad && fracRad < 0.75f ? box[idx[0]] : vertex[idx[0]]) * Units[idx[0]]; final += (0.25f < fracAngle && fracAngle < 0.75f ? box[idx[1]] : vertex[idx[1]]) * Units[idx[1]]; final += (scale[idx[2]] % 2.0f >= 0.5f || scale[idx[0]] < 1.0f ? box[idx[2]] : vertex[idx[2]]) * Units[idx[2]]; for (int i = 0; i <= 2; i++) { final[i] = ignoreAxis[i] ? pos[i] : final[i]; } return(PolarToWorld(final)); }
/// <summary> /// Fits a position vector into the grid. /// </summary> /// /// <returns> /// Aligned position vector. /// </returns> /// /// <param name="pos"> /// The position to align. /// </param> /// <param name="scale"> /// A simulated scale to decide how exactly to fit the poistion into the /// grid. /// </param> /// <param name="ignoreAxis"> /// Which axes should be ignored. /// </param> /// /// <remarks> /// This method aligns a point to the grid. The *scale* parameter is /// needed for legacy API compliance and is ignored. The <c>lockAxis</c> /// parameter lets you ignore individual axes. /// </remarks> public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis) { var vertex = NearestVertexG(pos); var box = NearestBoxG(pos); var grid = WorldToGrid(pos); var final = vertex; for (int i = 0; i < 3; ++i) { if (Mathf.Abs(grid[i] - box[i]) < Mathf.Abs(grid[i] - vertex[i])) { final[i] = box[i]; } } final = GridToWorld(final); for (int i = 0; i <= 2; i++) { final[i] = ignoreAxis[i] ? pos[i] : final[i]; } return(final); }
/// <summary>Fits a position vector into the grid.</summary> /// <returns>Aligned position vector.</returns> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the poistion into the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// /// This method aligns a point to the grid. The *scale* parameter is needed /// to simulate the “size” of point, which influences the resulting /// position like the scale of a Transform would do above. By default it’s /// set to one on all axes, placing the point at the centre of a box. If a /// component of @c scale is odd that component of the vector will be /// placed between edges, otherwise it will be placed on the nearest edge. /// The <c>lockAxis</c> parameter lets you ignore individual axes. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis) { var currentPosition = WorldToGrid(pos); var newPositionB = WorldToGrid(NearestBoxW(pos)); var newPositionV = WorldToGrid(NearestVertexW(pos)); var newPosition = new Vector3(); for (int i = 0; i <= 2; i++) { // vertex or box, depends on whether scale is a multiple of spacing newPosition[i] = (scale[i] / spacing[i]) % 2f <= 0.5f ? newPositionV[i] : newPositionB[i]; } // don't apply aligning if the axis has been locked+ for (int i = 0; i < 3; i++) { if (ignoreAxis[i]) { newPosition[i] = currentPosition[i]; } } return(GridToWorld(newPosition)); }
/// <summary>Scales a size vector to fit inside a grid.</summary> /// <returns>The re-scaled vector.</returns> /// <param name="scl">The vector to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// /// This method takes in a vector representing a size and fits it inside the grid. The *ignoreAxis* parameter lets you ignore individual axes. public abstract Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis);
/// <summary>Fits a position vector into the grid.</summary> /// <returns>Aligned position vector.</returns> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the poistion into the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// /// This method aligns a point to the grid. The *scale* parameter is needed /// to simulate the “size” of point, which influences the resulting /// position like the scale of a Transform would do above. By default it’s /// set to one on all axes, placing the point at the centre of a box. If a /// component of @c scale is odd that component of the vector will be /// placed between edges, otherwise it will be placed on the nearest edge. /// The <c>lockAxis</c> parameter lets you ignore individual axes. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis) { var currentPosition = WorldToGrid(pos); var newPositionB = WorldToGrid(NearestBoxW(pos)); var newPositionV = WorldToGrid(NearestVertexW(pos)); var newPosition = new Vector3(); for (int i = 0; i <=2; i++) { // vertex or box, depends on whether scale is a multiple of spacing newPosition[i] = (scale[i] / spacing[i]) % 2f <= 0.5f ? newPositionV[i] : newPositionB[i]; } // don't apply aligning if the axis has been locked+ for (int i = 0; i < 3; i++) { if (ignoreAxis[i]) { newPosition[i] = currentPosition[i]; } } return GridToWorld(newPosition); }
/// <summary>Scales a size to fit inside the grid.</summary> /// <returns>The re-scaled vector.</returns> /// <param name="scl">The vector to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// /// Scales a size to the nearest multiple of the grid’s spacing. The /// parameter *ignoreAxis* makes the function not touch the corresponding /// coordinate. public override Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis) { //Vector3 relScale = scl.GFModulo3(spacing); var relScale = new Vector3(scl.x % spacing.x, scl.y % spacing.y, scl.z % spacing.z); var newScale = Vector3.zero; for (int i = 0; i <= 2; i++) { newScale[i] = scl[i]; if (relScale[i] >= 0.5f * spacing[i]) { newScale[i] = newScale[i] - relScale[i] + spacing[i]; } else { newScale[i] = newScale[i] - relScale[i]; //if we went too far default to the spacing if (newScale[i] < spacing[i]) { newScale[i] = spacing[i]; } } } for (int i = 0; i < 3; i++) { if (ignoreAxis[i]) { newScale[i] = scl[i]; } } return newScale; }
/// <summary>Fits a position vector into the grid.</summary> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the poistion into the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// <returns>Aligned position vector.</returns> /// /// Fits a position inside the grid by using the object’s transform. /// Currently the object will snap either on edges or between, depending on /// which is closer, ignoring the <paramref name="scale"/> passed, but I /// might add an option for this in the future. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis) { float fracAngle = World2Angle(pos) / angle - Mathf.Floor(World2Angle(pos) / angle); float fracRad = World2Radius(pos) / radius - Mathf.Floor(World2Radius(pos) / radius); Vector3 vertex = NearestVertexP(pos); Vector3 box = NearestBoxP(pos); Vector3 final = Vector3.zero; final += (0.25f < fracRad && fracRad < 0.75f ? box[idx[0]] : vertex[idx[0]]) * Units[idx[0]]; final += (0.25f < fracAngle && fracAngle < 0.75f ? box[idx[1]] : vertex[idx[1]]) * Units[idx[1]]; final += (scale[idx[2]] % 2.0f >= 0.5f || scale[idx[0]] < 1.0f ? box[idx[2]] : vertex[idx[2]]) * Units[idx[2]]; for (int i = 0; i <= 2; i++) { final[i] = ignoreAxis[i] ? pos[i] : final[i]; } return PolarToWorld(final); }
/// <summary>Scales a size vector to fit inside a grid.</summary> /// <param name="scl">The vector to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// <returns>The re-scaled vector.</returns> /// /// Scales a given scale vector to the nearest multiple of the grid’s /// radius and depth, but does not change its position. The parameter /// <paramref name="ignoreAxis"/> makes the function not touch the /// corresponding coordinate. public override Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis) { Vector3 result = Vector3.Max(RoundMultiple(scl[idx[0]], radius) * locUnits[idx[0]] + scl[idx[1]] * locUnits[idx[1]] + RoundMultiple(scl[idx[2]], depth) * locUnits[idx[2]], radius * locUnits[idx[0]] + scl[idx[1]] * locUnits[idx[1]] + depth * locUnits[idx[2]]); for (int i = 0; i <= 2; i++) { result[i] = ignoreAxis[i] ? scl[i] : result[i]; } return result; }
/// <summary>Scales a size vector to fit inside a grid.</summary> /// <returns>The re-scaled vector.</returns> /// <param name="scale">The vector to scale.</param> /// <param name="lockAxis">The axes to ignore.</param> /// /// This method takes in a vector representing a size and scales it to the /// nearest multiple of the grid’s radius and depth. The <c>lockAxis</c> /// parameter lets you ignore individual axes. public override Vector3 ScaleVector3(Vector3 scale, BoolVector3 lockAxis) { var spacing = new Vector3(); for (int i = 0; i < 2; i++) { spacing[idxS[i]] = height; } spacing[idxS[2]] = depth; var relScale = new Vector3(scale.x % spacing.x, scale.y % spacing.y, scale.z % spacing.z); var newScale = new Vector3(); for (int i = 0; i <= 2; i++) { newScale[i] = scale[i]; if (relScale[i] >= 0.5f * spacing[i]) { //Debug.Log ("Grow by " + (spacing.x - relScale.x)); newScale[i] = newScale[i] - relScale[i] + spacing[i]; } else { //Debug.Log ("Shrink by " + relativeScale.x); newScale[i] = newScale[i] - relScale[i]; //if we went too far default to the spacing if (newScale[i] < spacing[i]) { newScale[i] = spacing[i]; } } } for (int i = 0; i < 3; i++) { if (lockAxis[i]) { newScale[i] = scale[i]; } } return newScale; }
/// <summary> /// Stub, doesn't do anything. /// </summary> /// <returns> /// The same vector. /// </returns> /// <param name="scl"> /// The vector to scale. /// </param> /// <param name="ignoreAxis"> /// The axes to ignore. /// </param> /// /// <remarks> /// This function *would* return the scales vector, but in a spheric grid /// were nothing is constant this idea does not make sense. It's a /// leftover from earlier versions of Grid Framework and is only included /// for API compliance. /// </remarks> public override Vector3 ScaleVector3(Vector3 scl, BoolVector3 ignoreAxis) { return(scl); }
/// <summary>Fits a position vector into the grid.</summary> /// <returns>Aligned position vector.</returns> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the poistion into the grid.</param> /// <param name="ignoreAxis">Which axes should be ignored.</param> /// /// Fits a position inside the grid by using the object’s transform. The exact position depends on whether the components of <paramref name="scale"/> are even or odd /// and the exact implementation can be found in the subclasses. The parameter <paramref name="ignoreAxis"/> makes the function not touch the corresponding coordinate. public abstract Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 ignoreAxis);
/// @overload /// It aligns the position and uses a default size of 1 x 1 x 1 while leaving the axes to the user, it is equal to /// <code>AlignVector3(pos, Vector3.one, lockAxis);</code> public Vector3 AlignVector3(Vector3 pos, BoolVector3 lockAxis) { return(AlignVector3(pos, Vector3.one, lockAxis)); }
/// @overload /// It aligns and rotates the Transform but leaves the axes to the user, it is equal to /// <code>AlignTransform(theTransform, true, lockAxis);</code> public void AlignTransform(Transform theTransform, BoolVector3 lockAxis) { AlignTransform(theTransform, true, lockAxis); }
public static Vector3 nonZeroToOneNegOne(this Vector3 v, float epsilon = 0.001f) { return(Vector3.Scale(v.sign(), BoolVector3.AGreaterThanB(v.abs(), new Vector3(epsilon, epsilon, epsilon)))); }
/// <summary>Scales a Transform to fit the grid (without moving it).</summary> /// <param name="theTransform">The Transform to scale.</param> /// <param name="ignoreAxis">The axes to ignore.</param> /// /// Scales a Transform to fit inside a grid. The parameter *ignoreAxis* makes the function not touch the corresponding coordinate. /// /// The resulting position depends on <see cref="ScaleVector3"/>, so please look up how that method works. public void ScaleTransform(Transform theTransform, BoolVector3 ignoreAxis) { theTransform.localScale = ScaleVector3(theTransform.localScale, ignoreAxis); }
/// <summary>Aligns and rotates a Transform.</summary> /// <param name="transform">The Transform to align.</param> /// <param name="lockAxis">Axis to ignore.</param> /// /// Aligns a Transform and the rotates it depending on its position inside /// the grid. This method combines two steps in one call for convenience. public void AlignRotateTransform(Transform transform, BoolVector3 lockAxis) { AlignTransform(transform, true, lockAxis); transform.rotation = World2Rotation(transform.position); }
public static string GetJson(BoolVector3 v) { return("[" + BoolStringNumber(v.x) + "," + BoolStringNumber(v.y) + "," + BoolStringNumber(v.z) + "]"); }
/// <summary>Fits a position vector into the grid.</summary> /// <param name="pos">The position to align.</param> /// <param name="scale">A simulated scale to decide how exactly to fit the position into the grid.</param> /// <param name="lockAxis">Which axes should be ignored.</param> /// <returns>The <c>Vector3</c>.</returns> /// /// Aligns a position vector to the grid by positioning it on the centre of /// the nearest face. Please refer to the user manual for more information. /// The parameter <c>lockAxis</c> makes the function not touch the corresponding /// coordinate. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, BoolVector3 lockAxis) { var newPos = NearestFaceW(pos); for (int i = 0; i < 3; i++) { if (lockAxis[i]) { newPos[i] = pos[i]; } } return newPos; }