public object Clone() { NPVoxNormalProcessorList clone = ScriptableObject.CreateInstance <NPVoxNormalProcessorList>(); foreach (NPVoxNormalProcessor processor in m_processorList) { clone.m_processorList.Add(processor.Clone() as NPVoxNormalProcessor); } return(clone); }
public void OnEnable() { if (NormalVarianceSeed == -1) { NormalVarianceSeed = Random.Range(0, int.MaxValue); } if (NormalProcessors == null) { NormalProcessors = ScriptableObject.CreateInstance <NPVoxNormalProcessorList>(); } }
public virtual void OnListChanged(NPVoxNormalProcessorList _list) { m_normalOutput = null; NPVoxNormalProcessorPreviewContext[] contexts = m_validPreviewContexts.ToArray(); foreach (NPVoxNormalProcessorPreviewContext context in contexts) { context.Invalidate(); } ClearInvalidPreviewContexts(); }
public override void Import() { base.Import(); if (NormalProcessors == null) { NormalProcessors = ScriptableObject.CreateInstance <NPVoxNormalProcessorList>(); } // Normal processor migration code if (NormalProcessors && NormalProcessors.RequiresMigration) { if (UnityEditor.AssetDatabase.GetAssetPath(NormalProcessors).Length == 0) { NormalProcessors.hideFlags = HideFlags.HideInHierarchy; if (NormalModePerVoxelGroup != null && NormalModePerVoxelGroup.Length > 0) { for (int i = 0; i < NormalModePerVoxelGroup.Length; i++) { NPVoxNormalProcessor_Voxel processorVoxel = NormalProcessors.AddProcessor <NPVoxNormalProcessor_Voxel>(); processorVoxel.NormalMode = NormalModePerVoxelGroup[i]; processorVoxel.AddVoxelGroupFilter(i); } } else { NPVoxNormalProcessor_Voxel processorVoxel = NormalProcessors.AddProcessor <NPVoxNormalProcessor_Voxel>(); processorVoxel.NormalMode = NormalMode; } NPVoxNormalProcessor_Variance processorVariance = NormalProcessors.AddProcessor <NPVoxNormalProcessor_Variance>(); processorVariance.NormalVarianceSeed = NormalVarianceSeed; processorVariance.NormalVariance = NormalVariance; NormalProcessors.AddToAsset(UnityEditor.AssetDatabase.GetAssetPath(this)); UnityEditor.EditorUtility.SetDirty(NormalProcessors); NormalProcessors.RequiresMigration = false; } NormalProcessors.RequiresMigration = false; } m_voxMeshData = NPVoxMeshGenerator.GenerateVoxMeshData(GetVoxModel(), VoxelSize, Optimization, BloodColorIndex, Loop, Cutout, Include); if (NormalProcessors != null) { NormalProcessors.OnImport(); } }
public override void OnListChanged(NPVoxNormalProcessorList _list) { base.OnListChanged(_list); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { NPVoxMeshOutput target = property.serializedObject.targetObject as NPVoxMeshOutput; NPVoxNormalProcessorList processorList = target.NormalProcessors; EditorGUI.BeginProperty(position, label, property); // Customize gui style Color previousBGColor = GUI.backgroundColor; Color previousFGColor = GUI.contentColor; GUI.backgroundColor = s_colorBackgroundGUIPrimary; GUI.backgroundColor = s_colorBackgroundGUIPrimary; // GUI.contentColor = s_colorForegroundGUI; // Doesn't seem to work // Header + Expand / Collapse Button GUILayout.BeginHorizontal(); GUILayout.Label("Normal Processors (" + processorList.GetProcessors().Count + ")", GUILayout.Width(s_widthHeaderLabel)); if (!m_expanded) { if (GUILayout.Button("Expand", GUILayout.Width(s_widthExpandButton))) { m_expanded = true; } } else { if (GUILayout.Button("Collapse", GUILayout.Width(s_widthExpandButton))) { m_expanded = false; } } GUILayout.EndHorizontal(); if (!m_expanded) { GUILayout.Space(12.0f); } // List management if (m_expanded) { Dictionary <string, System.Type> processorClasses = new Dictionary <string, System.Type>(); processorClasses.Add("<None>", null); List <System.Type> allTypes = new List <System.Type>(NPipeReflectionUtil.GetAllTypesWithAttribute(typeof(NPVoxAttributeNormalProcessorListItem))); allTypes = allTypes.OrderBy(x => (( NPVoxAttributeNormalProcessorListItem )x.GetCustomAttributes(typeof(NPVoxAttributeNormalProcessorListItem), true)[0]).ListPriority).ToList(); foreach (System.Type factoryType in allTypes) { NPVoxAttributeNormalProcessorListItem attr = ( NPVoxAttributeNormalProcessorListItem )factoryType.GetCustomAttributes(typeof(NPVoxAttributeNormalProcessorListItem), true)[0]; if (attr.ClassType.BaseType != typeof(NPVoxNormalProcessor)) { continue; } processorClasses.Add(attr.EditorName, factoryType); } string[] processorKeys = processorClasses.Keys.ToArray(); GUILayout.BeginHorizontal(); GUILayout.Space(s_widthTab); m_indexPopupAddProcessor = EditorGUILayout.Popup(m_indexPopupAddProcessor, processorKeys); bool optionAdded = GUILayout.Button("Add"); GUILayout.EndHorizontal(); if (optionAdded) { System.Type processorClass = processorClasses[processorKeys[m_indexPopupAddProcessor]]; if (processorClass != null) { if (UnityEditor.AssetDatabase.GetAssetPath(processorList).Length == 0) { target.IncludeSubAssets(UnityEditor.AssetDatabase.GetAssetPath(target)); } processorList.AddProcessor(processorClass) .AddToAsset(UnityEditor.AssetDatabase.GetAssetPath(target)); } } NPVoxNormalProcessor itemToMoveBack = null; NPVoxNormalProcessor itemToMoveForward = null; foreach (NPVoxNormalProcessor processor in processorList.GetProcessors()) { NPVoxAttributeNormalProcessorListItem attr = ( NPVoxAttributeNormalProcessorListItem )processor.GetType().GetCustomAttributes(typeof(NPVoxAttributeNormalProcessorListItem), true)[0]; GUILayout.Space(s_verticalSpacePerItem); GUILayout.BeginHorizontal(); GUILayout.Space(s_widthTab); GUILayout.Label(attr.EditorName, GUILayout.MinWidth(s_widthMinItemName)); GUILayout.Space(20.0f); GUI.backgroundColor = s_colorBackgroundGUISecondary; if (GUILayout.Button("View / Edit")) { NPVoxNormalProcessorPreview preview = NPVoxNormalProcessorPreview.ShowWindow(processor.GetType()); preview.SetContext(processor.GeneratePreviewContext(target)); } GUILayout.Space(20.0f); if (GUILayout.Button("^", GUILayout.Width(s_widthUpDownButton), GUILayout.ExpandWidth(true))) { itemToMoveBack = processor; } if (GUILayout.Button("v", GUILayout.Width(s_widthUpDownButton), GUILayout.ExpandWidth(true))) { itemToMoveForward = processor; } if (GUILayout.Button("X", GUILayout.Width(s_widthUpDownButton), GUILayout.ExpandWidth(true))) { processorList.DestroyProcessor(processor); break; } GUI.backgroundColor = s_colorBackgroundGUIPrimary; GUILayout.EndHorizontal(); processor.OnGUI(); GUILayout.Space(10.0f); } if (itemToMoveBack) { processorList.MoveProcessorBack(itemToMoveBack); itemToMoveBack = null; } if (itemToMoveForward) { processorList.MoveProcessorForward(itemToMoveForward); itemToMoveForward = null; } GUILayout.Space(s_verticalSpaceEnd); } // Restore previous gui style GUI.backgroundColor = previousBGColor; GUI.contentColor = previousFGColor; EditorGUI.EndProperty(); }
public static void CreateMesh( NPVoxModel model, Mesh mesh, Vector3 cubeSize, Vector3 NormalVariance, int NormalVarianceSeed = 0, NPVoxOptimization optimization = NPVoxOptimization.OFF, NPVoxNormalMode NormalMode = NPVoxNormalMode.SMOOTH, int BloodColorIndex = 0, NPVoxFaces loop = null, NPVoxFaces cutout = null, NPVoxFaces include = null, int MinVertexGroups = 1, NPVoxNormalMode[] NormalModePerVoxelGroup = null, NPVoxNormalProcessorList normalProcessors = null ) { bool hasVoxelGroups = model.HasVoxelGroups(); var vertices = new Vector3[model.NumVoxels * 8]; byte vertexGroupCount = model.NumVoxelGroups; var triangles = new int[vertexGroupCount, model.NumVoxels * 36]; var normals = new Vector3[model.NumVoxels * 8]; var tangents = new Vector4[model.NumVoxels * 8]; var colors = new Color[model.NumVoxels * 8]; var tmp = new NPVoxMeshTempData[model.NumVoxels]; int currentVertexIndex = 0; var currentTriangleIndex = new int[vertexGroupCount]; for (int i = 0; i < vertexGroupCount; i++) { currentTriangleIndex[i] = 0; } UnityEngine.Random.InitState(NormalVarianceSeed); if (loop == null) { loop = new NPVoxFaces(); } if (include == null) { include = new NPVoxFaces(1, 1, 1, 1, 1, 1); } NPVoxBox voxelsToInclude = model.BoundingBox; Vector3 cutoutOffset = Vector3.zero; if (cutout != null) { Vector3 originalCenter = voxelsToInclude.SaveCenter; voxelsToInclude.Left = (sbyte)Mathf.Abs(cutout.Left); voxelsToInclude.Down = (sbyte)Mathf.Abs(cutout.Down); voxelsToInclude.Back = (sbyte)Mathf.Abs(cutout.Back); voxelsToInclude.Right = (sbyte)(voxelsToInclude.Right - (sbyte)Mathf.Abs(cutout.Right)); voxelsToInclude.Up = (sbyte)(voxelsToInclude.Up - (sbyte)Mathf.Abs(cutout.Up)); voxelsToInclude.Forward = (sbyte)(voxelsToInclude.Forward - (sbyte)Mathf.Abs(cutout.Forward)); cutoutOffset = Vector3.Scale(originalCenter - voxelsToInclude.SaveCenter, cubeSize); } NPVoxToUnity npVoxToUnity = new NPVoxToUnity(model, cubeSize); Vector3 size = new Vector3( voxelsToInclude.Size.X * cubeSize.x, voxelsToInclude.Size.Y * cubeSize.y, voxelsToInclude.Size.Z * cubeSize.z ); NPVoxBox voxelNormalNeighbours = new NPVoxBox(new NPVoxCoord(-1, -1, -1), new NPVoxCoord(1, 1, 1)); // Collect temporary data to use for model generation int voxIndex = 0; foreach (NPVoxCoord voxCoord in voxelsToInclude.Enumerate()) { if (model.HasVoxel(voxCoord)) { tmp[voxIndex] = new NPVoxMeshTempData(); tmp[voxIndex].loop = loop; tmp[voxIndex].cutout = cutout; tmp[voxIndex].include = include; // Compute voxel center tmp[voxIndex].voxelCenter = npVoxToUnity.ToUnityPosition(voxCoord) + cutoutOffset; tmp[voxIndex].voxCoord = voxCoord; tmp[voxIndex].voxToUnity = npVoxToUnity; // Determine vertex group index tmp[voxIndex].vertexGroupIndex = 0; if (hasVoxelGroups) { tmp[voxIndex].vertexGroupIndex = model.GetVoxelGroup(voxCoord); } // Determine normal Mode if (NormalModePerVoxelGroup != null && NormalModePerVoxelGroup.Length > tmp[voxIndex].vertexGroupIndex) { tmp[voxIndex].normalMode = NormalModePerVoxelGroup[tmp[voxIndex].vertexGroupIndex]; } else { tmp[voxIndex].normalMode = NormalMode; } // do we have this side tmp[voxIndex].hasLeft = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.LEFT, loop)); tmp[voxIndex].hasRight = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.RIGHT, loop)); tmp[voxIndex].hasDown = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.DOWN, loop)); tmp[voxIndex].hasUp = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.UP, loop)); tmp[voxIndex].hasForward = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.FORWARD, loop)); tmp[voxIndex].hasBack = !model.HasVoxel(model.LoopCoord(voxCoord + NPVoxCoord.BACK, loop)); // do we actually want to include this side in our mesh // NOTE: cutout < 0 means we still render the mesh even though it is cutout // cutout > 0 means we don't render the mesh when cutout tmp[voxIndex].includeLeft = (tmp[voxIndex].hasLeft || (cutout.Left < 0 && voxCoord.X == voxelsToInclude.Left)) && include.Left == 1; tmp[voxIndex].includeRight = (tmp[voxIndex].hasRight || (cutout.Right < 0 && voxCoord.X == voxelsToInclude.Right)) && include.Right == 1; tmp[voxIndex].includeUp = (tmp[voxIndex].hasUp || (cutout.Up < 0 && voxCoord.Y == voxelsToInclude.Up)) && include.Up == 1; tmp[voxIndex].includeDown = (tmp[voxIndex].hasDown || (cutout.Down < 0 && voxCoord.Y == voxelsToInclude.Down)) && include.Down == 1; tmp[voxIndex].includeBack = (tmp[voxIndex].hasBack || (cutout.Back < 0 && voxCoord.Z == voxelsToInclude.Back)) && include.Back == 1; tmp[voxIndex].includeForward = (tmp[voxIndex].hasForward || (cutout.Forward < 0 && voxCoord.Z == voxelsToInclude.Forward)) && include.Forward == 1; tmp[voxIndex].isHidden = !tmp[voxIndex].hasForward && !tmp[voxIndex].hasBack && !tmp[voxIndex].hasLeft && !tmp[voxIndex].hasRight && !tmp[voxIndex].hasUp && !tmp[voxIndex].hasDown; if (tmp[voxIndex].isHidden && optimization == NPVoxOptimization.PER_VOXEL) { continue; } if (tmp[voxIndex].isHidden && BloodColorIndex > 0) { model.SetVoxel(voxCoord, (byte)BloodColorIndex); // WTF WTF WTF?!? we should not modify the MODEL in here !!!! elfapo: AAAAHHH NOOOO!!!! :O j.k. ;) } Color color = model.GetColor(voxCoord); // prepare cube vertices tmp[voxIndex].numVertices = 0; tmp[voxIndex].vertexIndexOffsetBegin = currentVertexIndex; if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeBack || tmp[voxIndex].includeLeft || tmp[voxIndex].includeDown) { tmp[voxIndex].vertexIndexOffsets[0] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[0]] = new Vector3(-0.5f, -0.5f, -0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeBack || tmp[voxIndex].includeRight || tmp[voxIndex].includeDown) { tmp[voxIndex].vertexIndexOffsets[1] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[1]] = new Vector3(0.5f, -0.5f, -0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeBack || tmp[voxIndex].includeLeft || tmp[voxIndex].includeUp) { tmp[voxIndex].vertexIndexOffsets[2] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[2]] = new Vector3(-0.5f, 0.5f, -0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeBack || tmp[voxIndex].includeRight || tmp[voxIndex].includeUp) { tmp[voxIndex].vertexIndexOffsets[3] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[3]] = new Vector3(0.5f, 0.5f, -0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeForward || tmp[voxIndex].includeLeft || tmp[voxIndex].includeDown) { tmp[voxIndex].vertexIndexOffsets[4] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[4]] = new Vector3(-0.5f, -0.5f, 0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeForward || tmp[voxIndex].includeRight || tmp[voxIndex].includeDown) { tmp[voxIndex].vertexIndexOffsets[5] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[5]] = new Vector3(0.5f, -0.5f, 0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeForward || tmp[voxIndex].includeLeft || tmp[voxIndex].includeUp) { tmp[voxIndex].vertexIndexOffsets[6] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[6]] = new Vector3(-0.5f, 0.5f, 0.5f); } if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeForward || tmp[voxIndex].includeRight || tmp[voxIndex].includeUp) { tmp[voxIndex].vertexIndexOffsets[7] = tmp[voxIndex].numVertices++; tmp[voxIndex].vertexPositionOffsets[tmp[voxIndex].vertexIndexOffsets[7]] = new Vector3(0.5f, 0.5f, 0.5f); } // add cube faces int i = currentTriangleIndex[tmp[voxIndex].vertexGroupIndex]; // back if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeBack) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[0]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[2]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[1]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[2]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[3]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[1]; } // Forward if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeForward) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[6]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[4]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[5]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[7]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[6]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[5]; } // right if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeRight) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[1]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[3]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[5]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[3]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[7]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[5]; } // left if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeLeft) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[0]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[4]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[2]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[2]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[4]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[6]; } // up if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeUp) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[2]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[6]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[3]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[3]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[6]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[7]; } // down if (optimization != NPVoxOptimization.PER_FACE || tmp[voxIndex].includeDown) { triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[0]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[1]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[4]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[1]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[5]; triangles[tmp[voxIndex].vertexGroupIndex, i++] = tmp[voxIndex].vertexIndexOffsetBegin + tmp[voxIndex].vertexIndexOffsets[4]; } // Tangents for (int t = 0; t < tmp[voxIndex].numVertices; t++) { // store voxel center for shader usage Vector4 tangent = new Vector4(); tangent.x = tmp[voxIndex].voxelCenter.x; tangent.y = tmp[voxIndex].voxelCenter.y; tangent.z = tmp[voxIndex].voxelCenter.z; // encode model size tangent.w = ((voxelsToInclude.Size.X & 0x7F) << 14) | ((voxelsToInclude.Size.Y & 0x7F) << 7) | (voxelsToInclude.Size.Z & 0x7F); tangents[tmp[voxIndex].vertexIndexOffsetBegin + t] = tangent; } // UVs for (int t = 0; t < tmp[voxIndex].numVertices; t++) { colors[tmp[voxIndex].vertexIndexOffsetBegin + t] = color; } // translate & scale vertices to voxel position for (int t = 0; t < tmp[voxIndex].numVertices; t++) { vertices[tmp[voxIndex].vertexIndexOffsetBegin + t] = tmp[voxIndex].voxelCenter + Vector3.Scale(tmp[voxIndex].vertexPositionOffsets[t], cubeSize); } currentTriangleIndex[tmp[voxIndex].vertexGroupIndex] = i; currentVertexIndex += tmp[voxIndex].numVertices; voxIndex++; } } // elfapo: Remove invalid voxel information Array.Resize(ref tmp, voxIndex); ////////////////////////////////////// NORMAL STAGES //////////////////////////////////////// // elfapo TODO: Test area 'Normal Processor' Move Normal Processor stages to Normal Processor Pipeline: //NPVoxNormalProcessor_Voxel generator = ScriptableObject.CreateInstance<NPVoxNormalProcessor_Voxel>(); //NPVoxNormalProcessor_Variance processor = ScriptableObject.CreateInstance<NPVoxNormalProcessor_Variance>(); //generator.InitOutputBuffer(normals); //processor.InitOutputBuffer(normals); //processor.NormalVariance = NormalVariance; //processor.NormalVarianceSeed = NormalVarianceSeed; //if (NormalModePerVoxelGroup != null && NormalModePerVoxelGroup.Length > 0) //{ // for (int i = 0; i < NormalModePerVoxelGroup.Length; i++) // { // generator.ClearVoxelGroupFilters(); // generator.AddVoxelGroupFilter(i); // generator.NormalMode = NormalModePerVoxelGroup[i]; // generator.Process(model, tmp, normals, normals); // } // processor.Process(model, tmp, normals, normals); //} //else //{ // generator.NormalMode = NormalMode; // generator.Process(model, tmp, normals, normals); // processor.Process(model, tmp, normals, normals); //} //ScriptableObject.DestroyImmediate(generator); //ScriptableObject.DestroyImmediate(processor); if (normalProcessors != null) { normalProcessors.Run(model, tmp, normals, normals); } ////////////////////////////////////////////////////////////////////////////////////////////// // shrink arrays as needed if (optimization != NPVoxOptimization.OFF) { Array.Resize(ref vertices, currentVertexIndex); Array.Resize(ref normals, currentVertexIndex); Array.Resize(ref tangents, currentVertexIndex); Array.Resize(ref colors, currentVertexIndex); } mesh.vertices = vertices; if (hasVoxelGroups) { mesh.subMeshCount = Math.Max(vertexGroupCount, MinVertexGroups); for (int i = 0; i < vertexGroupCount; i++) { int numberOfTrianglesForVertexGroup = currentTriangleIndex[i]; int[] trianglesForVertexGroup = new int[numberOfTrianglesForVertexGroup]; for (int j = 0; j < numberOfTrianglesForVertexGroup; j++) { trianglesForVertexGroup[j] = triangles[i, j]; } mesh.SetTriangles(trianglesForVertexGroup, i); } } else { int numberOfTrianglesForVertexGroup = currentTriangleIndex[0]; int[] trianglesForVertexGroup = new int[numberOfTrianglesForVertexGroup]; Buffer.BlockCopy(triangles, 0, trianglesForVertexGroup, 0, numberOfTrianglesForVertexGroup * sizeof(int)); if (MinVertexGroups < 2) { mesh.triangles = trianglesForVertexGroup; } else { mesh.subMeshCount = MinVertexGroups; mesh.SetTriangles(trianglesForVertexGroup, 0); } } mesh.normals = normals; mesh.tangents = tangents; mesh.colors = colors; mesh.bounds = new Bounds(Vector3.zero, size); if (NormalMode == NPVoxNormalMode.AUTO) { mesh.RecalculateNormals(); } }