internal void SetChannelBaseTextureWeights(MeshChannel channel, Dictionary <int, int> baseTexToMask, Dictionary <int, List <int> > maskToIndices) { var channelWeights = weights[channelMap[channel]]; for (int i = 0; i < channelWeights.Length; i++) { var vertexWeight = channelWeights[i]; foreach (var pair in baseTexToMask) { // Calculate the weight out of one already used for this mask, // and set the weight of the base texture to the remainder. // e.g. if all textures are on the same mask, the base texture is at // index 0 and the vector looks like: (0, 0.2, 0.3, 0.4). // Then 1 - (0.2 + 0.3 + 0.4) = 0.1, and the vector becomes: (0.1, 0.2, 0.3, 0.4). float value = 0f; List <int> indices; if (maskToIndices.TryGetValue(pair.Value, out indices)) { foreach (var ind in indices) { value += vertexWeight[ind]; } } vertexWeight[pair.Key] = 1 - value; } channelWeights[i] = vertexWeight; } weights[channelMap[channel]] = channelWeights; }
internal AttributeLayout(MeshChannel channel, ComponentIndex index, Vector2 range, int mask) { this.channel = channel; this.index = index; this.range = range; this.mask = mask; }
internal void ApplyAttributesFromUnityMesh(Mesh mesh, MeshChannel attrib = MeshChannel.All) { #pragma warning disable 0162 if (attrib == MeshChannel.All) { vertices = mesh.vertices; normals = mesh.normals; colors = mesh.colors32; tangents = mesh.tangents; mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV0), uv0); mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV2), uv1); mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV3), uv2); mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV4), uv3); /// Update submeshes only if there were none set or if we are no /// about to change the submeshCount. if (subMeshCount == 0 || mesh.subMeshCount == subMeshCount) { SetSubMeshes(mesh); RefreshTriangles(); } } else { if ((attrib & MeshChannel.Position) > 0) { vertices = mesh.vertices; } if ((attrib & MeshChannel.Normal) > 0) { normals = mesh.normals; } if ((attrib & MeshChannel.Color) > 0) { colors = mesh.colors32; } if ((attrib & MeshChannel.Tangent) > 0) { tangents = mesh.tangents; } if ((attrib & MeshChannel.UV0) > 0) { mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV0), uv0); } if ((attrib & MeshChannel.UV2) > 0) { mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV2), uv1); } if ((attrib & MeshChannel.UV3) > 0) { mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV3), uv2); } if ((attrib & MeshChannel.UV4) > 0) { mesh.GetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV4), uv3); } } #pragma warning restore 0162 }
internal AttributeLayout(MeshChannel channel, ComponentIndex index, Vector2 range, int mask, bool isBaseTexture = false) { this.channel = channel; this.index = index; this.range = range; this.mask = mask; this.isBaseTexture = isBaseTexture; }
/// <summary> /// Apply the mesh channel attributes to the graphics mesh. /// </summary> /// <param name="channel"></param> internal void ApplyMeshAttributes(MeshChannel channel = MeshChannel.All) { editMesh.ApplyAttributesToUnityMesh(_graphicsMesh, channel); if (m_PolybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream) { _graphicsMesh.UploadMeshData(false); } }
/// <summary> /// Apply the mesh channel attributes to the graphics mesh. /// </summary> /// <param name="channel"></param> internal void ApplyMeshAttributes(MeshChannel channel = MeshChannel.All) { editMesh.ApplyAttributesToUnityMesh(_graphicsMesh, channel); if (usingVertexStreams) { _graphicsMesh.UploadMeshData(false); } }
// Called every time the brush should apply itself to a valid target. Default is on mouse move. internal override void OnBrushApply(BrushTarget target, BrushSettings settings) { if (!m_LikelySupportsTextureBlending) { return; } splat_current.CopyTo(splat_cache); splat_cache.Apply(target.editableObject.editMesh); MeshChannel channelsChanged = MeshChannel.Color | MeshChannel.Tangent | MeshChannel.UV0 | MeshChannel.UV2 | MeshChannel.UV3 | MeshChannel.UV4; target.editableObject.modifiedChannels |= channelsChanged; base.OnBrushApply(target, settings); }
/// <summary> /// Scan a given mesh and create a mask mapping existing channels found. /// </summary> /// <param name="mesh">A valid mesh reference.</param> /// <returns>Mask defining existing information in <para name="mesh" />.</returns> internal static MeshChannel ToMask(Mesh mesh) { MeshChannel channels = MeshChannel.Null; if (mesh.vertices.Length > 0) { channels |= MeshChannel.Position; } if (mesh.normals.Length > 0) { channels |= MeshChannel.Normal; } if (mesh.colors32.Length > 0) { channels |= MeshChannel.Color; } if (mesh.tangents.Length > 0) { channels |= MeshChannel.Tangent; } if (mesh.uv.Length > 0) { channels |= MeshChannel.UV0; } if (mesh.uv2.Length > 0) { channels |= MeshChannel.UV2; } if (mesh.uv3.Length > 0) { channels |= MeshChannel.UV3; } if (mesh.uv4.Length > 0) { channels |= MeshChannel.UV4; } return(channels); }
/// <summary> /// Try to convert a MeshChannel value into it's corresponding UV index /// </summary> /// <param name="channel">value to be converted</param> /// <returns>Corresponding index if applicable, -1 otherwise</returns> internal static int UVChannelToIndex(MeshChannel channel) { if (channel == MeshChannel.UV0) { return(0); } else if (channel == MeshChannel.UV2) { return(1); } else if (channel == MeshChannel.UV3) { return(2); } else if (channel == MeshChannel.UV4) { return(3); } return(-1); }
internal static int ToInt(MeshChannel channel) { switch (channel) { case MeshChannel.Color: return(0); case MeshChannel.Tangent: return(1); case MeshChannel.UV0: return(2); case MeshChannel.UV2: return(3); case MeshChannel.UV3: return(4); case MeshChannel.UV4: return(5); } return(0); }
/// <summary> /// Applies mesh changes back to the pb_Object (if necessary). Optionally does a /// mesh rebuild. /// </summary> /// <param name="rebuildMesh">Only applies to ProBuilder meshes.</param> /// <param name="optimize">Determines if the mesh collisions are rebuilt (if that option is enabled) or if /// the mehs is a probuilder object, the mesh is optimized (condensed to share verts, other /// otpimziations etc) </param> internal void Apply(bool rebuildMesh, bool optimize = false) { if (m_PolybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream) { if (PolyEditor.instance.tool == BrushTool.RaiseLower || PolyEditor.instance.tool == BrushTool.Smooth) { if (s_RebuildNormals.value && (modifiedChannels & MeshChannel.Position) > 0) { PolyMeshUtility.RecalculateNormals(editMesh); } if (optimize) { graphicsMesh.RecalculateBounds(); UpdateMeshCollider(); } } editMesh.ApplyAttributesToUnityMesh(graphicsMesh, modifiedChannels); graphicsMesh.UploadMeshData(false); EditorUtility.SetDirty(gameObjectAttached.GetComponent <Renderer>()); if (m_PolybrushMesh.componentsCache.MeshFilter) { Undo.RecordObject(m_PolybrushMesh.componentsCache.MeshFilter, "Assign Polymesh to MeshFilter"); } if (m_PolybrushMesh) { m_PolybrushMesh.SynchronizeWithMeshRenderer(); } } #if PROBUILDER_4_0_OR_NEWER // if it's a probuilder object rebuild the mesh without optimization if (isProBuilderObject) { ProBuilderBridge.SetPositions(gameObjectAttached, editMesh.vertices); ProBuilderBridge.SetTangents(gameObjectAttached, editMesh.tangents); if (editMesh.colors != null && editMesh.colors.Length == editMesh.vertexCount) { Color[] colors = System.Array.ConvertAll(editMesh.colors, x => (Color)x); ProBuilderBridge.SetColors(gameObjectAttached, colors); } if (rebuildMesh) { ProBuilderBridge.ToMesh(gameObjectAttached); ProBuilderBridge.Refresh(gameObjectAttached, optimize ? ProBuilderBridge.RefreshMask.All : (ProBuilderBridge.RefreshMask.Colors | ProBuilderBridge.RefreshMask.Normals | ProBuilderBridge.RefreshMask.Tangents)); } } #endif if (m_PolybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream) { modifiedChannels = MeshChannel.Null; return; } if (PolyEditor.instance.tool == BrushTool.RaiseLower || PolyEditor.instance.tool == BrushTool.Smooth) { if (s_RebuildNormals.value)// && (modifiedChannels & MeshChannel.Position) > 0) { PolyMeshUtility.RecalculateNormals(editMesh); } if (optimize) { UpdateMeshCollider(); graphicsMesh.RecalculateBounds(); } } editMesh.ApplyAttributesToUnityMesh(graphicsMesh, modifiedChannels); if (m_PolybrushMesh.componentsCache.MeshFilter) { Undo.RecordObject(m_PolybrushMesh.componentsCache.MeshFilter, "Assign Polymesh to MeshFilter"); } m_PolybrushMesh.SynchronizeWithMeshRenderer(); modifiedChannels = MeshChannel.Null; }
internal AttributeLayout(MeshChannel channel, ComponentIndex index, Vector2 range, int mask, string targetProperty, Texture2D texture = null) : this(channel, index, range, mask) { this.propertyTarget = targetProperty; this.previewTexture = texture; }
internal AttributeLayout(MeshChannel channel, ComponentIndex index) : this(channel, index, Vector2.up, DefaultMask) { }
internal Vector4 this[MeshChannel channel] { get { return(GetVec4(map[channel])); } set { SetVec4(map[channel], value); } }
/// <summary> /// Lerp weights between lhs and rhs for value at the given index. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="strength"></param> /// <param name="index"></param> internal void LerpWeightOnSingleChannel(SplatSet lhs, SplatWeight rhs, float strength, MeshChannel channel, int index, int baseTexIndex) { if (!channelMap.ContainsKey(channel)) { return; } var channelIndex = channelMap[channel]; for (int i = 0; i < weightCount; i++) { float lerpedValue = Mathf.LerpUnclamped(lhs.weights[channelIndex][i][index], rhs[channel][index], strength); // replace the original value at index with the lerped value var newWeightVector = lhs.weights[channelIndex][i]; newWeightVector[index] = lerpedValue; if (baseTexIndex > -1) { newWeightVector[baseTexIndex] += (lhs.weights[channelIndex][i][index] - newWeightVector[index]); } this.weights[channelIndex][i] = newWeightVector; } }
/// <summary> /// Apply the vertex attributes to a UnityEngine mesh (does not set triangles) /// </summary> /// <param name="mesh"></param> /// <param name="attrib"></param> internal void ApplyAttributesToUnityMesh(Mesh mesh, MeshChannel attrib = MeshChannel.All) { // I guess the default value for attrib makes the compiler think that else is never // activated? #pragma warning disable 0162 if (attrib == MeshChannel.All) { mesh.vertices = vertices; mesh.normals = normals; mesh.colors32 = colors; mesh.tangents = tangents; mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV0), uv0); mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV2), uv1); mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV3), uv2); mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV4), uv3); mesh.subMeshCount = subMeshCount; for (int i = 0; i < subMeshCount; ++i) { mesh.SetIndices(m_SubMeshes[i].indexes, m_SubMeshes[i].topology, i); } RefreshTriangles(); } else { if ((attrib & MeshChannel.Position) > 0) { mesh.vertices = vertices; } if ((attrib & MeshChannel.Normal) > 0) { mesh.normals = normals; } if ((attrib & MeshChannel.Color) > 0) { mesh.colors32 = colors; } if ((attrib & MeshChannel.Tangent) > 0) { mesh.tangents = tangents; } if ((attrib & MeshChannel.UV0) > 0) { mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV0), uv0); } if ((attrib & MeshChannel.UV2) > 0) { mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV2), uv1); } if ((attrib & MeshChannel.UV3) > 0) { mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV3), uv2); } if ((attrib & MeshChannel.UV4) > 0) { mesh.SetUVs(MeshChannelUtility.UVChannelToIndex(MeshChannel.UV4), uv3); } } #pragma warning restore 0162 }