public void RemoveUnityMeshes(CSGModel model) { for (int i = 0; i < model.generatedMeshes.Length; i++) { var generatedMesh = model.generatedMeshes[i]; DecreaseRefCount(generatedMesh.meshKey); generatedMesh.sharedMesh = null; } }
static List <CSGGeneratedModelMesh> __allocateGeneratedMeshesTable = new List <CSGGeneratedModelMesh>(); // static to avoid allocations internal static void UpdateModelMeshDescriptions(CSGModel model) { var tree = model.Node; if (!tree.Valid) { return; } var meshTypes = CSGMeshQueryManager.GetMeshQuery(model); var meshDescriptions = tree.GetMeshDescriptions(meshTypes, model.VertexChannelMask); // Make sure we remove all old generated meshes sharedUnityMeshes.DecreaseMeshRefCount(model); // Check if the tree creates *any* meshes if (meshDescriptions == null) { model.generatedMeshes = __emptyGeneratedMeshesTable; componentGenerator.RemoveAllGeneratedComponents(model); if (PostUpdateModel != null) { PostUpdateModel(model); } return; } __allocateGeneratedMeshesTable.Clear(); for (int d = 0; d < meshDescriptions.Length; d++) { var meshDescription = meshDescriptions[d]; // Make sure the meshDescription actually holds a mesh if (meshDescription.vertexCount == 0 || meshDescription.indexCount == 0) { continue; } // Make sure the mesh is valid if (meshDescription.vertexCount >= MaxVertexCount) { Debug.LogError("Mesh has too many vertices (" + meshDescription.vertexCount + " > " + MaxVertexCount + ")"); continue; } // Add the generated mesh to the list __allocateGeneratedMeshesTable.Add(new CSGGeneratedModelMesh { meshDescription = meshDescription, meshKey = new GeneratedMeshKey(meshDescription) }); } // TODO: compare with existing generated meshes, only rebuild stuff for things that have actually changed model.generatedMeshes = __allocateGeneratedMeshesTable.ToArray(); }
public void ReuseExistingMeshes(CSGModel model) { for (int i = 0; i < model.generatedMeshes.Length; i++) { var generatedMesh = model.generatedMeshes[i]; // See if we already know a mesh that has the same description generatedMesh.sharedMesh = ReturnUnityMeshAndIncreaseRefCountIfExists(generatedMesh.meshKey); generatedMesh.needsUpdate = !generatedMesh.sharedMesh; } }
public void Register(CSGModel model) { // Destroy leftover components in model lookups DestroyAllRegisteredGeneratedComponentsInModel(model); // Rebuild component lookup tables used by generatedMeshes BuildGeneratedComponentLookupTables(model); models.Add(model); }
void UpdateComponentFlags(CSGModel model, ModelState modelState, Component component, GameObject componentGameObject, Transform componentTransform, string componentName, bool notEditable) { const HideFlags GameObjectHideFlags = HideFlags.NotEditable; const HideFlags TransformHideFlags = HideFlags.NotEditable;// | HideFlags.HideInInspector; if (componentGameObject.name != componentName) { componentGameObject.name = componentName; } // TODO: make components turn off this flag when its gameObject is directly selected? HideFlags ComponentHideFlags = HideFlags.HideInHierarchy | (notEditable ? HideFlags.NotEditable : HideFlags.None); // Avoids MeshCollider showing wireframe // Some components could theoretically just be put on the model itself, so we don't modify any flags then if (componentGameObject == modelState.modelGameObject) { return; } // Make sure we're always a child of the current data container if (componentTransform.parent != modelState.containerTransform) { componentTransform.SetParent(modelState.containerTransform, false); componentTransform.localPosition = Vector3.zero; componentTransform.localRotation = Quaternion.identity; componentTransform.localScale = Vector3.one; } if (componentGameObject.layer != modelState.layer) { componentGameObject.layer = modelState.layer; } if (componentGameObject.hideFlags != GameObjectHideFlags) { componentGameObject.hideFlags = GameObjectHideFlags; } if (componentTransform.hideFlags != TransformHideFlags) { componentTransform.hideFlags = TransformHideFlags; } if (component.hideFlags != ComponentHideFlags) { component.hideFlags = ComponentHideFlags; } #if UNITY_EDITOR var prevStaticFlags = UnityEditor.GameObjectUtility.GetStaticEditorFlags(componentGameObject); if (prevStaticFlags != modelState.staticFlags) { UnityEditor.GameObjectUtility.SetStaticEditorFlags(componentGameObject, modelState.staticFlags); } #endif }
private CSGColliderComponents CreateColliderComponents(CSGModel model, GeneratedMeshDescription meshDescription) { var gameObject = CreateComponentGameObject(model, GeneratedMeshColliderName, typeof(MeshCollider)); var colliderComponents = new CSGColliderComponents { meshCollider = gameObject.GetComponent <MeshCollider>(), gameObject = gameObject, transform = gameObject.transform }; return(colliderComponents); }
public bool RetrieveUnityMesh(CSGModel model, GeneratedMeshDescription meshDescription, UnityEngine.Mesh sharedMesh) { // Retrieve the generatedMesh, and store it in the Unity Mesh model.generatedMeshContents = model.Node.GetGeneratedMesh(meshDescription, model.generatedMeshContents); if (model.generatedMeshContents == null) { return(false); } model.generatedMeshContents.CopyTo(sharedMesh); SetHasLightmapUVs(sharedMesh, false); return(true); }
private void RemoveContainerGameObject(CSGModel model) { if (model.GeneratedDataTransform) { model.GeneratedDataContainer.hideFlags = HideFlags.None; model.GeneratedDataTransform.hideFlags = HideFlags.None; CSGNodeHierarchyManager.ignoreNextChildrenChanged = true; CSGObjectUtility.SafeDestroy(model.GeneratedDataContainer); CSGNodeHierarchyManager.ignoreNextChildrenChanged = false; model.GeneratedDataContainer = null; model.GeneratedDataTransform = null; } }
private CSGRenderComponents CreateRenderComponents(CSGModel model, GeneratedMeshDescription meshDescription) { var gameObject = CreateComponentGameObject(model, GeneratedMeshRendererName, typeof(MeshFilter), typeof(MeshRenderer)); var renderComponents = new CSGRenderComponents { meshFilter = gameObject.GetComponent <MeshFilter>(), meshRenderer = gameObject.GetComponent <MeshRenderer>(), gameObject = gameObject, transform = gameObject.transform }; return(renderComponents); }
public static void RemoveContainerFlags(CSGModel model) { if (model.GeneratedDataContainer) { model.GeneratedDataContainer.hideFlags = HideFlags.None; } foreach (var lists in model.generatedRenderComponents.Values) { foreach (var item in lists) { if (item.gameObject) { item.gameObject.hideFlags = HideFlags.None; } if (item.transform) { item.transform.hideFlags = HideFlags.None; } if (item.meshFilter) { item.meshFilter.hideFlags = HideFlags.None; } if (item.meshRenderer) { item.meshRenderer.hideFlags = HideFlags.None; } } } foreach (var lists in model.generatedMeshColliders.Values) { foreach (var item in lists) { if (item.gameObject) { item.gameObject.hideFlags = HideFlags.None; } if (item.transform) { item.transform.hideFlags = HideFlags.None; } if (item.meshCollider) { item.meshCollider.hideFlags = HideFlags.None; } } } }
// TODO: improve naming public static CSGModel GetModelForNode(CSGModel overrideModel = null) { if (overrideModel) { BrushMeshAssetFactory.ActiveModel = overrideModel; return(overrideModel); } var activeModel = BrushMeshAssetFactory.ActiveModel; if (!activeModel) { activeModel = BrushMeshAssetFactory.Create <CSGModel>("Model"); BrushMeshAssetFactory.ActiveModel = activeModel; } return(activeModel); }
// NOTE: assumes that if a meshCollider is passed to this, it is -valid- // do any checking outside of this method, and make sure everything that // needs to be cleaned up, IS cleaned up private bool UpdateOrCreateColliderComponents(CSGModel model, ModelState modelState, GeneratedMeshDescription meshDescription, ref CSGColliderComponents colliderComponents) { bool updated = false; if (colliderComponents == null) { colliderComponents = CreateColliderComponents(model, meshDescription); updated = true; } UpdateColliderComponents(model, modelState, meshDescription, colliderComponents); UpdateComponentFlags(model, modelState, colliderComponents.meshCollider, colliderComponents.gameObject, colliderComponents.transform, GeneratedMeshColliderName, notEditable: true); if (!colliderComponents.meshCollider.enabled) { colliderComponents.meshCollider.enabled = true; } return(updated); }
public void CreateNewMeshes(CSGModel model) { // Separate loop so we can re-use meshes when creating new meshes for (int i = 0; i < model.generatedMeshes.Length; i++) { var generatedMesh = model.generatedMeshes[i]; if (generatedMesh.sharedMesh != null) { continue; } // If not, create a new mesh ... generatedMesh.sharedMesh = CreateNewUnityMesh(generatedMesh.meshKey); RetrieveUnityMesh(model, generatedMesh.meshDescription, generatedMesh.sharedMesh); } }
public static MeshQuery[] GetMeshQuery(CSGModel model) { // TODO: make this depended on the model settings / helper surface view settings if (model.CreateRenderComponents && model.CreateColliderComponents) { return(defaultModelSettings); } if (model.CreateRenderComponents) { return(renderOnly); } else { return(collisionOnly); } }
public static GameObject FindContainerGameObject(CSGModel model) { if (!model) { return(null); } var transform = model.transform; for (int i = 0, childCount = transform.childCount; i < childCount; i++) { var child = transform.GetChild(i); if (child.name == GeneratedContainerName) { return(child.gameObject); } } return(null); }
private void UpdateContainerFlags(CSGModel model, ModelState modelState) { const HideFlags GameObjectHideFlags = HideFlags.NotEditable; const HideFlags TransformHideFlags = HideFlags.NotEditable;// | HideFlags.HideInInspector; var gameObject = modelState.containerGameObject; var transform = modelState.containerTransform; if (gameObject.name != GeneratedContainerName) { gameObject.name = GeneratedContainerName; } // Make sure we're always a child of the model if (transform.parent != modelState.modelTransform) { transform.SetParent(modelState.modelTransform, false); transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one; } if (gameObject.layer != modelState.layer) { gameObject.layer = modelState.layer; } if (gameObject.hideFlags != GameObjectHideFlags) { gameObject.hideFlags = GameObjectHideFlags; } if (transform.hideFlags != TransformHideFlags) { transform.hideFlags = TransformHideFlags; } #if UNITY_EDITOR var prevStaticFlags = UnityEditor.GameObjectUtility.GetStaticEditorFlags(gameObject); if (prevStaticFlags != modelState.staticFlags) { UnityEditor.GameObjectUtility.SetStaticEditorFlags(gameObject, modelState.staticFlags); } #endif }
internal void BuildGeneratedComponentLookupTables(CSGModel model) { for (int i = 0; i < model.generatedMeshes.Length; i++) { var generatedMesh = model.generatedMeshes[i]; if (generatedMesh.renderComponents != null && generatedMesh.renderComponents.meshRenderer && generatedMesh.renderComponents.meshFilter) { var material = generatedMesh.renderComponents.meshRenderer.sharedMaterial; List <CSGRenderComponents> components; if (!model.generatedRenderComponents.TryGetValue(material, out components)) { components = new List <CSGRenderComponents>(); model.generatedRenderComponents[material] = components; } components.Add(generatedMesh.renderComponents); model.generatedComponents.Add(generatedMesh.renderComponents.transform); } if (generatedMesh.colliderComponents != null && generatedMesh.colliderComponents.meshCollider) { var meshCollider = generatedMesh.colliderComponents.meshCollider; var material = meshCollider.sharedMaterial; List <CSGColliderComponents> components; if (!model.generatedMeshColliders.TryGetValue(material, out components)) { components = new List <CSGColliderComponents>(); model.generatedMeshColliders[material] = components; } components.Add(generatedMesh.colliderComponents); model.generatedComponents.Add(generatedMesh.colliderComponents.transform); } } }
private void UpdateRenderComponents(CSGModel model, ModelState modelState, GeneratedMeshDescription meshDescription, CSGRenderComponents renderComponents) { var meshRenderer = renderComponents.meshRenderer; #if UNITY_EDITOR updateMeshRenderers.Add(meshRenderer); #endif var query = meshDescription.meshQuery.LayerQuery; meshRenderer.receiveShadows = ((query & LayerUsageFlags.ReceiveShadows) == LayerUsageFlags.ReceiveShadows); switch (query & (LayerUsageFlags.Renderable | LayerUsageFlags.CastShadows)) { case LayerUsageFlags.None: meshRenderer.enabled = false; break; case LayerUsageFlags.Renderable: meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; meshRenderer.enabled = true; break; case LayerUsageFlags.CastShadows: meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly; meshRenderer.enabled = true; break; case LayerUsageFlags.RenderCastShadows: meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; meshRenderer.enabled = true; break; } #if UNITY_EDITOR UnityEditor.EditorUtility.SetSelectedRenderState(meshRenderer, UnityEditor.EditorSelectedRenderState.Hidden); #endif }
public static bool FindFirstWorldIntersection(CSGModel model, Vector3 worldRayStart, Vector3 worldRayEnd, int filterLayerParameter0, int visibleLayers, out CSGTreeBrushIntersection foundIntersection) { return(FindFirstWorldIntersection(model, worldRayStart, worldRayEnd, filterLayerParameter0, visibleLayers, null, null, out foundIntersection)); }
public static bool EndPicking(HideFlagsState state, UnityEngine.Object pickedObject, out CSGModel model) { model = null; if (state == null || state.hideFlags == null) { return(false); } foreach (var pair in state.hideFlags) { pair.Key.hideFlags = pair.Value; } if (object.Equals(pickedObject, null)) { return(false); } if (state.generatedComponents == null) { return(false); } bool pickedGeneratedComponent = false; foreach (var pair in state.generatedComponents) { if (pickedObject == pair.Key) { model = pair.Value; pickedGeneratedComponent = true; break; } } return(pickedGeneratedComponent); }
private void UpdateColliderComponents(CSGModel model, ModelState modelState, GeneratedMeshDescription meshDescription, CSGColliderComponents colliderComponents) { var meshCollider = colliderComponents.meshCollider; updateMeshColliders.Add(meshCollider); }
private void UpdateComponents(CSGModel model, List <MeshRenderer> meshRenderers, List <MeshCollider> meshColliders) { if (meshRenderers.Count > 0) { var renderSettings = model.RenderSettings; #if UNITY_EDITOR // Warning: calling new UnityEditor.SerializedObject with an empty array crashes Unity var serializedObject = new UnityEditor.SerializedObject(meshRenderers.ToArray()); #if !UNITY_2017_2_OR_ABOVE var dynamicOccludeeProp = serializedObject.FindProperty("m_DynamicOccludee"); if (dynamicOccludeeProp != null) { dynamicOccludeeProp.boolValue = renderSettings.dynamicOccludee; } #endif #if !UNITY_2018_2_OR_ABOVE var renderingLayerMaskProp = serializedObject.FindProperty("m_RenderingLayerMask"); if (renderingLayerMaskProp != null) { renderingLayerMaskProp.intValue = (int)renderSettings.renderingLayerMask; } #endif var importantGIProp = serializedObject.FindProperty("m_ImportantGI"); importantGIProp.boolValue = renderSettings.importantGI; var optimizeUVsProp = serializedObject.FindProperty("m_PreserveUVs"); optimizeUVsProp.boolValue = renderSettings.optimizeUVs; var ignoreNormalsForChartDetectionProp = serializedObject.FindProperty("m_IgnoreNormalsForChartDetection"); ignoreNormalsForChartDetectionProp.boolValue = renderSettings.ignoreNormalsForChartDetection; var scaleInLightmapProp = serializedObject.FindProperty("m_ScaleInLightmap"); scaleInLightmapProp.floatValue = renderSettings.scaleInLightmap; var autoUVMaxDistanceProp = serializedObject.FindProperty("m_AutoUVMaxDistance"); autoUVMaxDistanceProp.floatValue = renderSettings.autoUVMaxDistance; var autoUVMaxAngleProp = serializedObject.FindProperty("m_AutoUVMaxAngle"); autoUVMaxAngleProp.floatValue = renderSettings.autoUVMaxAngle; var minimumChartSizeProp = serializedObject.FindProperty("m_MinimumChartSize"); minimumChartSizeProp.intValue = renderSettings.minimumChartSize; #if UNITY_2017_2_OR_ABOVE var stitchLightmapSeamsProp = serializedObject.FindProperty("m_StitchLightmapSeams"); stitchLightmapSeamsProp.boolValue = renderSettings.stitchLightmapSeams; #endif #endif for (int i = 0; i < meshRenderers.Count; i++) { var meshRenderer = meshRenderers[i]; meshRenderer.lightProbeProxyVolumeOverride = renderSettings.lightProbeProxyVolumeOverride; meshRenderer.probeAnchor = renderSettings.probeAnchor; meshRenderer.motionVectorGenerationMode = renderSettings.motionVectorGenerationMode; meshRenderer.reflectionProbeUsage = renderSettings.reflectionProbeUsage; meshRenderer.lightProbeUsage = renderSettings.lightProbeUsage; #if UNITY_2017_2_OR_ABOVE meshRenderer.allowOcclusionWhenDynamic = renderSettings.allowOcclusionWhenDynamic; #endif #if UNITY_2018_2_OR_ABOVE meshRenderer.renderingLayerMask = renderSettings.renderingLayerMask; #endif } } if (meshColliders.Count > 0) { var colliderSettings = model.ColliderSettings; for (int i = 0; i < meshColliders.Count; i++) { var meshCollider = meshColliders[i]; meshCollider.cookingOptions = colliderSettings.cookingOptions; meshCollider.convex = colliderSettings.convex; meshCollider.isTrigger = colliderSettings.isTrigger; } } }
internal void BuildComponents(CSGModel model, ModelState modelState, CSGGeneratedModelMesh generatedMesh) { Material renderMaterial = null; PhysicMaterial physicsMaterial = null; if (generatedMesh.meshDescription.surfaceParameter != 0) { var type = generatedMesh.meshDescription.meshQuery.LayerParameterIndex; var parameter = generatedMesh.meshDescription.surfaceParameter; switch (type) { case LayerParameterIndex.LayerParameter1: renderMaterial = CSGSurfaceAssetManager.GetRenderMaterialByInstanceID(parameter); break; case LayerParameterIndex.LayerParameter2: physicsMaterial = CSGSurfaceAssetManager.GetPhysicsMaterialByInstanceID(parameter); break; } } else { var type = generatedMesh.meshDescription.meshQuery.LayerParameterIndex; switch (type) { case LayerParameterIndex.LayerParameter1: renderMaterial = CSGMaterialManager.DefaultMaterial; break; case LayerParameterIndex.LayerParameter2: physicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; break; } } if (renderMaterial != null) { generatedMesh.renderComponents = null; List <CSGRenderComponents> components; if (modelState.existingRenderComponents.TryGetValue(renderMaterial, out components)) { while (components.Count > 0) { var curComponents = components[0]; components.RemoveAt(0); if (components.Count == 0) { modelState.existingRenderComponents.Remove(renderMaterial); model.generatedComponents.Remove(curComponents.transform); } if (curComponents.meshRenderer && curComponents.meshFilter) { generatedMesh.renderComponents = curComponents; break; } } } var forceUpdate = UpdateOrCreateRenderComponents(model, modelState, generatedMesh.meshDescription, ref generatedMesh.renderComponents); if (generatedMesh.renderComponents.meshRenderer.sharedMaterial != renderMaterial) { generatedMesh.renderComponents.meshRenderer.sharedMaterial = renderMaterial; } if (generatedMesh.renderComponents.meshFilter.sharedMesh != generatedMesh.sharedMesh) { generatedMesh.renderComponents.meshFilter.sharedMesh = generatedMesh.sharedMesh; } if (generatedMesh.needsUpdate || forceUpdate) { #if UNITY_EDITOR if ((modelState.staticFlags & UnityEditor.StaticEditorFlags.LightmapStatic) == UnityEditor.StaticEditorFlags.LightmapStatic) { generatedMesh.renderComponents.meshRenderer.realtimeLightmapIndex = -1; generatedMesh.renderComponents.meshRenderer.lightmapIndex = -1; generatedMesh.renderComponents.uvLightmapUpdateTime = Time.realtimeSinceStartup; haveUVsToUpdate = true; } #endif } } else if (physicsMaterial != null) { generatedMesh.colliderComponents = null; List <CSGColliderComponents> components; if (modelState.existingMeshColliders.TryGetValue(physicsMaterial, out components)) { while (components.Count > 0) { var curComponents = components[0]; components.RemoveAt(0); if (components.Count == 0) { modelState.existingMeshColliders.Remove(physicsMaterial); model.generatedComponents.Remove(curComponents.transform); } if (curComponents.meshCollider) { generatedMesh.colliderComponents = curComponents; break; } } } UpdateOrCreateColliderComponents(model, modelState, generatedMesh.meshDescription, ref generatedMesh.colliderComponents); if (generatedMesh.colliderComponents.meshCollider.sharedMesh != generatedMesh.sharedMesh) { generatedMesh.colliderComponents.meshCollider.sharedMesh = generatedMesh.sharedMesh; } if (generatedMesh.colliderComponents.meshCollider.sharedMaterial != physicsMaterial) { generatedMesh.colliderComponents.meshCollider.sharedMaterial = physicsMaterial; } } generatedMesh.needsUpdate = false; }
public static T Create <T>(CSGModel model) where T : CSGNode { return(Create <T>(null, model ? model.transform : null, Vector3.zero, Quaternion.identity, Vector3.one)); }
public static bool FindFirstWorldIntersection(CSGModel model, Vector3 worldRayStart, Vector3 worldRayEnd, int filterLayerParameter0, int visibleLayers, GameObject[] ignore, GameObject[] filter, out CSGTreeBrushIntersection foundIntersection) { foundIntersection = new CSGTreeBrushIntersection(); foundIntersection.surfaceIntersection.distance = float.PositiveInfinity; if (!model || !model.isActiveAndEnabled) { return(false); } CSGTreeNode[] ignoreBrushes = null; HashSet <int> ignoreInstanceIDs = null; HashSet <int> filterInstanceIDs = null; if (ignore != null) { //var ignoreBrushList = new HashSet<CSGTreeBrush>(); ignoreInstanceIDs = new HashSet <int>(); foreach (var go in ignore) { var node = go.GetComponent <CSGNode>(); if (node) { //node.GetAllTreeBrushes(ignoreBrushList); ignoreInstanceIDs.Add(node.GetInstanceID()); } }/* * if (ignoreBrushList.Count > 0) * { * // TODO: fix this, ignorebrushes doesn't remove the brush completely, but that's not necessarily correct * // for example: another brush that is not ignored, subtracts from a brush that's ignored (so its insides should be selectable) * ignoreBrushes = new CSGTreeNode[ignoreBrushList.Count]; * int index = 0; * foreach(var brush in ignoreBrushList) * { * ignoreBrushes[index] = brush; * index++; * } * }*/ } if (filter != null) { filterInstanceIDs = new HashSet <int>(); foreach (var go in filter) { var node = go.GetComponent <CSGNode>(); if (node) { filterInstanceIDs.Add(node.GetInstanceID()); } } } var tree = model.Node; if ((ignoreInstanceIDs != null && ignoreInstanceIDs.Contains(model.GetInstanceID()))) { return(false); } if ((filterInstanceIDs != null && !filterInstanceIDs.Contains(model.GetInstanceID()))) { return(false); } if (((1 << model.gameObject.layer) & visibleLayers) == 0) { return(false); } var query = CSGMeshQueryManager.GetMeshQuery(model); // We only accept RayCasts into this model if it's visible if (!CSGMeshQueryManager.IsVisible(query)) { return(false); } Vector3 treeRayStart; Vector3 treeRayEnd; var transform = model.transform; if (transform) { var worldToLocalMatrix = transform.worldToLocalMatrix; treeRayStart = worldToLocalMatrix.MultiplyPoint(worldRayStart); treeRayEnd = worldToLocalMatrix.MultiplyPoint(worldRayEnd); } else { treeRayStart = worldRayStart; treeRayEnd = worldRayEnd; } var treeIntersections = tree.RayCastMulti(CSGMeshQueryManager.GetMeshQuery(model), treeRayStart, treeRayEnd, filterLayerParameter0, ignoreBrushes); if (treeIntersections == null) { return(false); } bool found = false; for (var i = 0; i < treeIntersections.Length; i++) { var intersection = treeIntersections[i]; var brush = intersection.brush; var instanceID = brush.UserID; if ((filterInstanceIDs != null && !filterInstanceIDs.Contains(instanceID))) { continue; } if ((ignoreInstanceIDs != null && ignoreInstanceIDs.Contains(instanceID))) { continue; } if (intersection.surfaceIntersection.distance < foundIntersection.surfaceIntersection.distance) { foundIntersection = intersection; found = true; } } return(found); }
public static T Create <T>(string name, CSGModel model, Vector3 position, Quaternion rotation, Vector3 scale) where T : CSGNode { return(Create <T>(name, model ? model.transform : null, position, rotation, scale)); }
private static void GenerateLightmapUVsForInstance(CSGModel model, CSGRenderComponents renderComponents, Mesh generatedMesh) { // Avoid light mapping multiple times, when the same mesh is used on multiple MeshRenderers if (CSGSharedUnityMeshManager.HasLightmapUVs(generatedMesh)) { return; } if (renderComponents == null || !renderComponents.meshFilter || !renderComponents.meshRenderer) { return; } var uvSettings = model.UVGenerationSettings; var param = new UnityEditor.UnwrapParam(); UnityEditor.UnwrapParam.SetDefaults(out param); param.angleError = Mathf.Clamp(uvSettings.angleError, SerializableUnwrapParam.minAngleError, SerializableUnwrapParam.maxAngleError); param.areaError = Mathf.Clamp(uvSettings.areaError, SerializableUnwrapParam.minAreaError, SerializableUnwrapParam.maxAreaError); param.hardAngle = Mathf.Clamp(uvSettings.hardAngle, SerializableUnwrapParam.minHardAngle, SerializableUnwrapParam.maxHardAngle); param.packMargin = Mathf.Clamp(uvSettings.packMarginPixels, SerializableUnwrapParam.minPackMargin, SerializableUnwrapParam.maxPackMargin) / 256.0f; var oldVertices = generatedMesh.vertices; if (oldVertices.Length == 0) { return; } // TODO: can we avoid creating a temporary Mesh? if not; make sure CSGSharedUnityMeshManager is handled correctly var oldUV = generatedMesh.uv; var oldNormals = generatedMesh.normals; var oldTangents = generatedMesh.tangents; var oldTriangles = generatedMesh.triangles; var tempMesh = new Mesh { vertices = oldVertices, normals = oldNormals, uv = oldUV, tangents = oldTangents, triangles = oldTriangles }; var lightmapGenerationTime = UnityEditor.EditorApplication.timeSinceStartup; UnityEditor.Unwrapping.GenerateSecondaryUVSet(tempMesh, param); lightmapGenerationTime = UnityEditor.EditorApplication.timeSinceStartup - lightmapGenerationTime; // TODO: make a nicer text here Debug.Log("Generating lightmap UVs (by Unity) for the mesh '" + generatedMesh.name + "' of the Model named \"" + model.name + "\"\n" + "\tUV generation in " + (lightmapGenerationTime * 1000) + " ms\n", model); // Modify the original mesh, since it is shared generatedMesh.uv2 = tempMesh.uv2; // static lightmaps generatedMesh.uv3 = tempMesh.uv3; // real-time lightmaps CSGSharedUnityMeshManager.SetHasLightmapUVs(generatedMesh, true); renderComponents.meshFilter.sharedMesh = null; renderComponents.meshFilter.sharedMesh = generatedMesh; UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(model.gameObject.scene); }
public void RemoveAllGeneratedComponents(CSGModel model) { DestroyAllRegisteredGeneratedComponentsInModel(model); RemoveContainerGameObject(model); }
public static T Create <T>(string name, CSGModel model, Matrix4x4 trsMatrix) where T : CSGNode { return(Create <T>(name, model ? model.transform : null, trsMatrix)); }
static readonly ModelState __modelState = new ModelState(); // static to avoid allocations public void Rebuild(CSGModel model) { if (model.generatedMeshes == null || model.generatedMeshes.Length == 0) { // Destroy leftover components in model lookups DestroyAllRegisteredGeneratedComponentsInModel(model); RemoveContainerGameObject(model); } else { if (!model.IsInitialized) { model.OnInitialize(); } if (!model.GeneratedDataTransform) { DestroyAllRegisteredGeneratedComponentsInModel(model); CreateContainerGameObject(model); } var modelGameObject = model.gameObject; #if UNITY_EDITOR __modelState.staticFlags = UnityEditor.GameObjectUtility.GetStaticEditorFlags(modelGameObject); #endif __modelState.modelGameObject = modelGameObject; __modelState.modelTransform = model.hierarchyItem.Transform; __modelState.layer = modelGameObject.layer; __modelState.containerGameObject = model.GeneratedDataContainer; __modelState.containerTransform = model.GeneratedDataTransform; __modelState.existingRenderComponents = model.generatedRenderComponents; __modelState.existingMeshColliders = model.generatedMeshColliders; UpdateModelFlags(model); UpdateContainerFlags(model, __modelState); // Build components for generatedMesh, re-use existing components if they're available (& remove from lookups) updateMeshRenderers.Clear(); updateMeshColliders.Clear(); for (int i = 0; i < model.generatedMeshes.Length; i++) { var generatedMesh = model.generatedMeshes[i]; BuildComponents(model, __modelState, generatedMesh); } UpdateComponents(model, updateMeshRenderers, updateMeshColliders); updateMeshRenderers.Clear(); updateMeshColliders.Clear(); // Destroy leftover components in model lookups DestroyAllRegisteredGeneratedComponentsInModel(model); // Rebuild component lookup tables used by generatedMeshes BuildGeneratedComponentLookupTables(model); var containerTransform = __modelState.containerTransform; for (int c = containerTransform.childCount - 1; c >= 0; c--) { var child = containerTransform.GetChild(c); if (!model.generatedComponents.Contains(child)) { CSGObjectUtility.SafeDestroy(child.gameObject); } } } // to avoid dangling memory __modelState.modelGameObject = null; __modelState.modelTransform = null; __modelState.containerGameObject = null; __modelState.containerTransform = null; }