public CGBoundsGroup AddGroup(string name) { var grp = new CGBoundsGroup(name); Groups.Add(grp); Dirty = true; return(grp); }
CGSpot getSpot(int itemID, ref CGBoundsGroup group, ref CGBounds bounds, float startDist, float remainingDistance) { var spot = new CGSpot(itemID); float pathF = Path.DistanceToF(startDist + bounds.Depth / 2); Vector3 pos = Vector3.zero; Vector3 tan = Vector3.forward; Vector3 up = Vector3.up; float crossF = getCrossValue((startDist - StartDistance) / Length, group); if (group.RotationMode != CGBoundsGroup.RotationModeEnum.Independent) { if (UseVolume) { Volume.InterpolateVolume(pathF, crossF, out pos, out tan, out up); } else { Path.Interpolate(pathF, crossF, out pos, out tan, out up); } switch (group.RotationMode) { case CGBoundsGroup.RotationModeEnum.Direction: up = Vector3.up; break; case CGBoundsGroup.RotationModeEnum.Horizontal: up = Vector3.up; tan.y = 0; break; } } else { pos = (UseVolume) ? Volume.InterpolateVolumePosition(pathF, crossF) : Path.InterpolatePosition(pathF); } // Orientation Setup if (Path.SourceIsManaged) { spot.Rotation = Quaternion.LookRotation(tan, up) * Quaternion.Euler(group.RotationOffset.x + group.RotationScatter.x * Random.Range(-1, 1), group.RotationOffset.y + group.RotationScatter.y * Random.Range(-1, 1), group.RotationOffset.z + group.RotationScatter.z * Random.Range(-1, 1)); spot.Position = pos + spot.Rotation * new Vector3(0, group.Height.Next, 0); } else { spot.Rotation = Quaternion.LookRotation(tan, up) * Quaternion.Euler(group.RotationOffset.x + group.RotationScatter.x * Random.Range(-1, 1), group.RotationOffset.y + group.RotationScatter.y * Random.Range(-1, 1), group.RotationOffset.z + group.RotationScatter.z * Random.Range(-1, 1)); spot.Position = pos + spot.Rotation * new Vector3(0, group.Height.Next, 0); } return(spot); }
float getCrossValue(float globalF, CGBoundsGroup group) { switch (group.DistributionMode) { case CGBoundsGroup.DistributionModeEnum.Parent: return(DTMath.MapValue(-0.5f, 0.5f, CrossBase + m_CrossCurve.Evaluate(globalF) + group.PositionOffset.Next)); case CGBoundsGroup.DistributionModeEnum.Self: return(DTMath.MapValue(-0.5f, 0.5f, group.PositionOffset.Next)); } return(0); }
float getMinGroupDepth(CGBoundsGroup group) { float r = group.SpaceBefore.Low + group.SpaceAfter.Low; CGBounds b; for (int i = 0; i < group.ItemCount; i++) { b = getItemBounds(group.Items[i].Index); if (b) { r += b.Depth; } } return(r); }
float getCrossValue(float globalF, CGBoundsGroup group) { switch (group.DistributionMode) { case CGBoundsGroup.DistributionModeEnum.Parent: return DTMath.MapValue(-0.5f, 0.5f, CrossBase + m_CrossCurve.Evaluate(globalF) + group.PositionOffset.Next); case CGBoundsGroup.DistributionModeEnum.Self: return DTMath.MapValue(-0.5f, 0.5f, group.PositionOffset.Next); } return 0; }
float getMinGroupDepth(CGBoundsGroup group) { float r = group.SpaceBefore.Low + group.SpaceAfter.Low; CGBounds b; for (int i = 0; i < group.ItemCount; i++) { b = getItemBounds(group.Items[i].Index); if (b) r += b.Depth; } return r; }
CGSpot getSpot(int itemID, ref CGBoundsGroup group, ref CGBounds bounds, float startDist, float remainingDistance) { var spot = new CGSpot(itemID); float pathF = Path.DistanceToF(startDist + bounds.Depth / 2); Vector3 pos = Vector3.zero; Vector3 tan = Vector3.forward; Vector3 up = Vector3.up; float crossF = getCrossValue((startDist - StartDistance) / Length, group); if (group.RotationMode != CGBoundsGroup.RotationModeEnum.Independent) { if (UseVolume) Volume.InterpolateVolume(pathF, crossF, out pos, out tan, out up); else Path.Interpolate(pathF, crossF, out pos, out tan, out up); switch (group.RotationMode) { case CGBoundsGroup.RotationModeEnum.Direction: up = Vector3.up; break; case CGBoundsGroup.RotationModeEnum.Horizontal: up = Vector3.up; tan.y = 0; break; } } else pos = (UseVolume) ? Volume.InterpolateVolumePosition(pathF, crossF) : Path.InterpolatePosition(pathF); // Orientation Setup if (Path.SourceIsManaged) { spot.Rotation = Quaternion.LookRotation(tan, up) * Quaternion.Euler(group.RotationOffset.x + group.RotationScatter.x * Random.Range(-1,1), group.RotationOffset.y + group.RotationScatter.y * Random.Range(-1, 1), group.RotationOffset.z + group.RotationScatter.z * Random.Range(-1, 1)); spot.Position = pos + spot.Rotation * new Vector3(0, group.Height.Next, 0); } else { spot.Rotation = Quaternion.LookRotation(tan, up) * Quaternion.Euler(group.RotationOffset.x + group.RotationScatter.x * Random.Range(-1, 1), group.RotationOffset.y + group.RotationScatter.y * Random.Range(-1, 1), group.RotationOffset.z + group.RotationScatter.z * Random.Range(-1, 1)); spot.Position = pos + spot.Rotation * new Vector3(0, group.Height.Next, 0); } return spot; }
/*! \cond PRIVATE */ GroupSet addGroupItems(CGBoundsGroup group, ref List<CGSpot> spots, ref float remainingLength, ref float currentDistance, bool calcLengthOnly = false) { if (group.ItemCount == 0) return null; CGBounds currentBounds; int itemID; int added = 0; float gapBefore = group.SpaceBefore.Next; float gapAfter = group.SpaceAfter.Next; float remain = remainingLength - gapBefore; GroupSet vGroup = null; GroupSet endItems = new GroupSet(); float dist = currentDistance + gapBefore; if (calcLengthOnly) { vGroup = new GroupSet(); vGroup.Group = group; vGroup.Length = gapBefore + gapAfter; } // Fixed Start Item(s) for (int i = 0; i < group.FirstRepeating; i++) { itemID = group.Items[i].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { if (calcLengthOnly) { vGroup.Length += currentBounds.Depth; vGroup.Items.Add(itemID); vGroup.Distances.Add(dist); } else spots.Add(getSpot(itemID, ref group, ref currentBounds, dist, remainingLength)); dist += currentBounds.Depth; added++; } else { if (group.KeepTogether && added > 0) { spots.RemoveRange(spots.Count - added, added); } break; } } } if (remain > 0) { float endDist = 0; // Fixed End Item(s) for (int i = group.LastRepeating + 1; i < group.ItemCount; i++) { itemID = group.Items[i].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { endItems.Length += currentBounds.Depth; endItems.Items.Add(itemID); endItems.Distances.Add(endDist); endDist += currentBounds.Depth; } else break; } } if (remain > 0) { // Mid Items int itemIdx; for (int i = group.FirstRepeating; i <= group.LastRepeating; i++) { itemIdx = (group.RepeatingOrder == CurvyRepeatingOrderEnum.Row) ? i : group.getRandomItemINTERNAL(); itemID = group.Items[itemIdx].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { if (calcLengthOnly) { vGroup.Length += currentBounds.Depth; vGroup.Items.Add(itemID); vGroup.Distances.Add(dist); } else spots.Add(getSpot(itemID, ref group, ref currentBounds, dist, remainingLength)); dist += currentBounds.Depth; added++; } else { if (group.KeepTogether && added > 0) { spots.RemoveRange(spots.Count - added, added); } break; } } } } if (remain > 0 || !group.KeepTogether) { for (int e = 0; e < endItems.Items.Count; e++) { var b = getItemBounds(endItems.Items[e]); spots.Add(getSpot(endItems.Items[e], ref group, ref b, dist + endItems.Distances[e], remainingLength)); dist += b.Depth; } } } remainingLength = remain - gapAfter; currentDistance = dist + gapAfter; return vGroup; }
public void RemoveGroup(CGBoundsGroup group) { Groups.Remove(group); Dirty = true; }
public CGBoundsGroup AddGroup(string name) { var grp = new CGBoundsGroup(name); Groups.Add(grp); Dirty = true; return grp; }
/*! \cond PRIVATE */ GroupSet addGroupItems(CGBoundsGroup group, ref List <CGSpot> spots, ref float remainingLength, ref float currentDistance, bool calcLengthOnly = false) { if (group.ItemCount == 0) { return(null); } CGBounds currentBounds; int itemID; int added = 0; float gapBefore = group.SpaceBefore.Next; float gapAfter = group.SpaceAfter.Next; float remain = remainingLength - gapBefore; GroupSet vGroup = null; GroupSet endItems = new GroupSet(); float dist = currentDistance + gapBefore; if (calcLengthOnly) { vGroup = new GroupSet(); vGroup.Group = group; vGroup.Length = gapBefore + gapAfter; } // Fixed Start Item(s) for (int i = 0; i < group.FirstRepeating; i++) { itemID = group.Items[i].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { if (calcLengthOnly) { vGroup.Length += currentBounds.Depth; vGroup.Items.Add(itemID); vGroup.Distances.Add(dist); } else { spots.Add(getSpot(itemID, ref group, ref currentBounds, dist, remainingLength)); } dist += currentBounds.Depth; added++; } else { if (group.KeepTogether && added > 0) { spots.RemoveRange(spots.Count - added, added); } break; } } } if (remain > 0) { float endDist = 0; // Fixed End Item(s) for (int i = group.LastRepeating + 1; i < group.ItemCount; i++) { itemID = group.Items[i].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { endItems.Length += currentBounds.Depth; endItems.Items.Add(itemID); endItems.Distances.Add(endDist); endDist += currentBounds.Depth; } else { break; } } } if (remain > 0) { // Mid Items int itemIdx; for (int i = group.FirstRepeating; i <= group.LastRepeating; i++) { itemIdx = (group.RepeatingOrder == CurvyRepeatingOrderEnum.Row) ? i : group.getRandomItemINTERNAL(); itemID = group.Items[itemIdx].Index; currentBounds = getItemBounds(itemID); if (currentBounds) { remain -= currentBounds.Depth; if (remain > 0) { if (calcLengthOnly) { vGroup.Length += currentBounds.Depth; vGroup.Items.Add(itemID); vGroup.Distances.Add(dist); } else { spots.Add(getSpot(itemID, ref group, ref currentBounds, dist, remainingLength)); } dist += currentBounds.Depth; added++; } else { if (group.KeepTogether && added > 0) { spots.RemoveRange(spots.Count - added, added); } break; } } } } if (remain > 0 || !group.KeepTogether) { for (int e = 0; e < endItems.Items.Count; e++) { var b = getItemBounds(endItems.Items[e]); spots.Add(getSpot(endItems.Items[e], ref group, ref b, dist + endItems.Distances[e], remainingLength)); dist += b.Depth; } } } remainingLength = remain - gapAfter; currentDistance = dist + gapAfter; return(vGroup); }
void OnRenderTab(DTInspectorNode node) { int grpIdx = node.Index - 2; if (grpIdx >= 0 && grpIdx < Target.GroupCount) { var pGroup = serializedObject.FindProperty(string.Format("m_Groups.Array.data[{0}]", grpIdx)); if (pGroup != null) { var group = Target.Groups[grpIdx]; var pItems = pGroup.FindPropertyRelative("m_Items"); if (pItems != null) { if (mCurrentGroup != null && mCurrentGroup != group) { mGroupItemsList = null; } if (mGroupItemsList == null) { mCurrentGroup = group; mGroupItemsList = new ReorderableList(pItems.serializedObject, pItems); mGroupItemsList.draggable = true; mGroupItemsList.drawHeaderCallback = (Rect Rect) => { EditorGUI.LabelField(Rect, "Items"); }; mGroupItemsList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { #region --- bool fix = (index <group.FirstRepeating || index> group.LastRepeating); if (fix) { DTHandles.DrawSolidRectangleWithOutline(rect.ShiftBy(0, -1), new Color(0, 0, 0.5f, 0.2f), new Color(0, 0, 0, 0)); } var prop = pItems.FindPropertyRelative(string.Format("Array.data[{0}]", index)); var pIndex = prop.FindPropertyRelative("Index"); rect.height = EditorGUIUtility.singleLineHeight; var r = new Rect(rect); EditorGUI.LabelField(new Rect(rect.x, rect.y, 30, rect.height), "#" + index.ToString() + ":"); r.x += 30; r.width = rect.width / 2 - 50; var bn = Target.BoundsNames; var bi = Target.BoundsIndices; if (bn.Length == 0) { pIndex.intValue = EditorGUI.IntField(r, "", pIndex.intValue); } else { EditorGUI.IntPopup(r, pIndex, bn, bi, new GUIContent("")); } r.x += r.width + 10; r.width = rect.width / 2; if (!fix && group.RepeatingOrder == CurvyRepeatingOrderEnum.Random) { EditorGUI.PropertyField(r, prop.FindPropertyRelative("m_Weight"), new GUIContent("")); } #endregion }; mGroupItemsList.onAddCallback = (ReorderableList l) => { group.Items.Insert(Mathf.Clamp(l.index + 1, 0, group.ItemCount), new CGBoundsGroupItem()); group.LastRepeating++; Target.Dirty = true; EditorUtility.SetDirty(Target); }; mGroupItemsList.onRemoveCallback = (ReorderableList l) => { group.Items.RemoveAt(l.index); group.LastRepeating--; Target.Dirty = true; EditorUtility.SetDirty(Target); }; } mGroupItemsList.DoLayoutList(); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_RepeatingItems")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_RepeatingOrder")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_KeepTogether")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_SpaceBefore")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_SpaceAfter")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_DistributionMode"), new GUIContent("Mode")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_PositionOffset")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_Height")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_RotationMode")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_RotationOffset")); EditorGUILayout.PropertyField(pGroup.FindPropertyRelative("m_RotationScatter")); } } } }