public override Vector3 AlignVector3(Vector3 position, Vector3 scale, GFBoolVector3 lockAxis, bool beTolerant = true) { Vector3 currentPosition = WorldToGrid(position); Vector3 newPosition = WorldToGrid(FindNearestBox(position)); bool withinTolerance = true; for (int i = 0; i <=2; i++){ if((scale[i] / spacing[i]) % 2f <= 0.5f){ // i.e. the scale is an even multiple of spacing newPosition[i] = newPosition[i] + Mathf.Sign (WorldToGrid(position)[i] % 1f - Mathf.Sign(WorldToGrid(position)[i])*0.5f) * 0.5f; } } //check tolerance for (int j = 0; j <=2; j++){ // Debug.Log(Mathf.Abs(currenPosition[j] - newPosition[j])); if (Mathf.Abs(currentPosition[j] - newPosition[j]) >= 0.01f && Mathf.Abs(currentPosition[j] - newPosition[j]) <0.9f) withinTolerance = false; } // don't apply aligning if the axis has been locked+ for(int i = 0; i < 3; i++){ if(lockAxis[i]) newPosition[i] = currentPosition[i]; } if(beTolerant && withinTolerance) return position; return GridToWorld(newPosition); }
//_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- #region AlignScaleMethods public override Vector3 AlignVector3(Vector3 position, Vector3 scale, GFBoolVector3 lockAxis) { Vector3 currentPosition = WorldToGrid(position); Vector3 newPositionB = WorldToGrid(NearestBoxW(position)); Vector3 newPositionV = WorldToGrid(NearestVertexW(position)); Vector3 newPosition = new Vector3(); for (int i = 0; i <= 2; i++) { // vertex or box, depends on whether scale is a multiple of spacing //Debug.Log( "spacing [i] : " + spacing[i] ); //spacing格子的单位大小(10代表在世界中占10米) //Debug.Log( "scale [i] : " + scale[i] ); 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 (lockAxis[i]) { newPosition[i] = currentPosition[i]; } } //Debug.Log( "GridToWorld(newPosition) : " + GridToWorld( newPosition ) ); return(GridToWorld(newPosition)); }
public override Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 lockAxis) { 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] = lockAxis[i] ? scl[i] : result[i]; } return(result); }
/// <summary>Fits a Transform inside the grid, but does not scale 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> public void AlignTransform(Transform theTransform, bool rotate, GFBoolVector3 ignoreAxis) { Quaternion oldRotation = theTransform.rotation; theTransform.rotation = transform.rotation; theTransform.position = AlignVector3(theTransform.position, theTransform.lossyScale, ignoreAxis); if (!rotate) { theTransform.rotation = oldRotation; } }
public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis) { Vector3 newPos = FindNearestFace(pos); for (int i = 0; i < 3; i++) { if (lockAxis[i]) { newPos[i] = pos[i]; } } return(newPos); }
public override Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 lockAxis) { Vector3 spacing = new Vector3(); for (int i = 0; i < 2; i++) { spacing[idx[i]] = height; } spacing[idx[2]] = depth; Vector3 relScale = scl.GFModulo3(spacing); Vector3 newScale = new Vector3(); for (int i = 0; i <= 2; i++) { newScale[i] = scl[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] = scl[i]; } } return(newScale); }
public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis) { 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 += (scale [idx[0]] % 2.0f >= 0.5f || scale [idx[0]] < 1.0f ? box [idx[0]] : vertex [idx[0]]) * units[idx[0]]; % <-- another idea based on scale 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] = lockAxis[i] ? pos[i] : final[i]; } return(PolarToWorld(final)); }
//_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- #region AlignScaleMethods public override Vector3 AlignVector3(Vector3 position, Vector3 scale, GFBoolVector3 lockAxis, bool beTolerant = true) { Vector3 currentPosition = WorldToGrid(position); Vector3 newPosition = WorldToGrid(FindNearestBox(position)); bool withinTolerance = true; for (int i = 0; i <= 2; i++) { if ((scale[i] / spacing[i]) % 2f <= 0.5f) // i.e. the scale is an even multiple of spacing { newPosition[i] = newPosition[i] + Mathf.Sign(WorldToGrid(position)[i] % 1f - Mathf.Sign(WorldToGrid(position)[i]) * 0.5f) * 0.5f; } } //check tolerance for (int j = 0; j <= 2; j++) { // Debug.Log(Mathf.Abs(currenPosition[j] - newPosition[j])); if (Mathf.Abs(currentPosition[j] - newPosition[j]) >= 0.01f && Mathf.Abs(currentPosition[j] - newPosition[j]) < 0.9f) { withinTolerance = false; } } // don't apply aligning if the axis has been locked+ for (int i = 0; i < 3; i++) { if (lockAxis[i]) { newPosition[i] = currentPosition[i]; } } if (beTolerant && withinTolerance) { return(position); } return(GridToWorld(newPosition)); }
public void ScaleTransform(Transform theTransform, GFBoolVector3 lockAxis) { theTransform.localScale = ScaleVector3(theTransform.localScale, lockAxis); }
public abstract Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis, bool beTolerant);
public Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis) { return AlignVector3(pos, scale, lockAxis, true); }
public void AlignTransform(Transform theTransform, bool rotate, GFBoolVector3 lockAxis, bool beTolerant) { Quaternion oldRotation = theTransform.rotation; theTransform.rotation = transform.rotation; theTransform.position = AlignVector3(theTransform.position, theTransform.lossyScale, lockAxis, beTolerant); if(!rotate) theTransform.rotation = oldRotation; }
/// <summary>Similar to AlignTransform, except only for Vectors</summary> /// <returns>The aligned vector</returns> /// <param name="pos">Position in world space</param> /// <param name="scale">Scale used to place the vector</param> /// <param name="ignoreAxis">Which axes should be ignored</param> public abstract Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 ignoreAxis);
/// <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="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 parameter lets you ignore individual axes. public override Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 lockAxis){ Vector3 spacing = new Vector3(); for(int i = 0; i < 2; i++){ spacing[idxS[i]] = height; } spacing[idxS[2]] = depth; Vector3 relScale = scl.GFModulo3(spacing); Vector3 newScale = new Vector3(); for (int i = 0; i <= 2; i++){ newScale[i] = scl[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] = scl[i]; } return newScale; }
public Vector3 AlignVector3(Vector3 pos, GFBoolVector3 lockAxis) { return(AlignVector3(pos, Vector3.one, lockAxis)); }
/// <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, GFBoolVector3 ignoreAxis) { Vector3 relScale = scl.GFModulo3(spacing); Vector3 newScale = Vector3.zero; for (int i = 0; i <= 2; i++) { newScale[i] = scl[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 (ignoreAxis[i]) { newScale[i] = scl[i]; } } return newScale; }
/// <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, GFBoolVector3 ignoreAxis) { Vector3 currentPosition = WorldToGrid(pos); Vector3 newPositionB = WorldToGrid(NearestBoxW(pos)); Vector3 newPositionV = WorldToGrid(NearestVertexW(pos)); Vector3 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> /// <param name="scl">The vector to scale.</param> /// <param name="lockAxis">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 @c lockAxis makes the function not touch the corresponding coordinate. public override Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 lockAxis){ 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] = lockAxis[i] ? scl[i] : result[i];} return result; }
/// <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="lockAxis">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 @c scale passed, but I might add an option for this in the future. public override Vector3 AlignVector3 (Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis) { 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 += (scale [idx[0]] % 2.0f >= 0.5f || scale [idx[0]] < 1.0f ? box [idx[0]] : vertex [idx[0]]) * units[idx[0]]; % <-- another idea based on scale 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] = lockAxis[i] ? pos[i] : final[i];} return PolarToWorld(final); }
/** * @brief Aligns and rotates a Transform. * @param theTransform The Transform to align. * @param lockAxis Axis to ignore. * * Aligns a Transform and the rotates it depending on its position inside the grid. * This method cobines two steps in one call for convenience. */ public void AlignRotateTransform (Transform theTransform, GFBoolVector3 lockAxis) { AlignTransform(theTransform, true, lockAxis); theTransform.rotation = World2Rotation(theTransform.position); }
/// <summary>Similar to SclaeTransform, except only for Vectors</summary> /// <param name="scl">The vector to scale</param> /// <param name="lockAxis">The axes to ignore</param> public abstract Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 ignoreAxis);
public abstract Vector3 ScaleVector3(Vector3 scl, GFBoolVector3 lockAxis);
/// <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="lockAxis">Which axes should be ignored.</param> /// <returns>The vector3.</returns> /// /// Aligns a poistion 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 lockAxis makes the function not touch the corresponding coordinate. public override Vector3 AlignVector3(Vector3 pos, Vector3 scale, GFBoolVector3 lockAxis){ Vector3 newPos = NearestFaceW(pos); for(int i = 0; i < 3; i++){ if(lockAxis[i]) newPos[i] = pos[i]; } return newPos; }
/// <summary>Scales a Transform to fit the grid but does not move it</summary> /// <param name="theTransform">The Transform to scale</param> /// <param name="lockAxis">The axes to ignore</param> public void ScaleTransform(Transform theTransform, GFBoolVector3 ignoreAxis) { theTransform.localScale = ScaleVector3(theTransform.localScale, ignoreAxis); }
public Vector3 AlignVector3(Vector3 pos, GFBoolVector3 lockAxis, bool beTolerant = true) { return(AlignVector3(pos, Vector3.one, lockAxis, beTolerant)); }
public void AlignTransform(Transform theTransform, bool rotate, GFBoolVector3 lockAxis) { AlignTransform(theTransform, rotate, lockAxis, true); }
public void AlignTransform(Transform theTransform, GFBoolVector3 lockAxis) { AlignTransform(theTransform, true, lockAxis); }
public void AlignRotateTransform(Transform theTransform, bool rotate, GFBoolVector3 lockAxis) { AlignTransform(theTransform, rotate, lockAxis); theTransform.rotation = World2Rotation(theTransform.position); }