void AddVoxelTextures(VoxelDefinition vd) { if (vd == null) { return; } if (vd.index > 0 && vd.index < voxelDefinitionsCount && voxelDefinitions [vd.index] == vd) { return; // already added } // Resize voxel definitions array? if (voxelDefinitionsCount >= voxelDefinitions.Length) { VoxelDefinition[] resized = new VoxelDefinition[voxelDefinitions.Length * 2]; for (int k = 0; k < voxelDefinitionsCount; k++) { resized [k] = voxelDefinitions [k]; } voxelDefinitions = resized; } voxelDefinitions [voxelDefinitionsCount] = vd; vd.index = (ushort)voxelDefinitionsCount; voxelDefinitionsCount++; voxelDefinitionsDict [vd.name] = vd; // Autofix certain non supported properties if (vd.navigatable) { vd.navigatable = vd.renderType.supportsNavigation(); } // Check if custom model has collider vd.modelUsesCollider = false; if (vd.renderType == RenderType.Custom) { if (vd.model == null) { // custom voxel is missing model so we assign a default cube vd.model = GetDefaultVoxelPrefab(); vd.opaque = 15; } if (vd.model != null) { // annotate if model has collider if (vd.gpuInstancing) { if (vd.createGameObject) { vd.modelUsesCollider = vd.model.GetComponent <Collider> () != null; } } else { vd.modelUsesCollider = vd.model.GetComponent <Collider> () != null; } } if (vd.textureSide == null) { // assign default texture sample for inventory icons Material modelMaterial = vd.material; if (modelMaterial != null && modelMaterial.mainTexture != null && modelMaterial.mainTexture is Texture2D) { vd.icon = (Texture2D)modelMaterial.mainTexture; } } } // Assign default material Material mat = vd.GetOverrideMaterial(effectiveUseGeometryShaders); if (mat == null) { switch (vd.renderType) { case RenderType.Opaque: case RenderType.Opaque6tex: vd.materialBufferIndex = INDICES_BUFFER_OPAQUE; break; case RenderType.Cutout: vd.materialBufferIndex = INDICES_BUFFER_CUTOUT; break; case RenderType.CutoutCross: vd.materialBufferIndex = INDICES_BUFFER_CUTXSS; break; case RenderType.Water: vd.materialBufferIndex = INDICES_BUFFER_WATER; break; case RenderType.Transp6tex: vd.materialBufferIndex = INDICES_BUFFER_TRANSP; break; case RenderType.OpaqueNoAO: vd.materialBufferIndex = INDICES_BUFFER_OPNOAO; break; } } else { // Assign material index int materialBufferIndex; if (!materialIndices.TryGetValue(mat, out materialBufferIndex)) { if (lastBufferIndex < materials.Length - 1) { lastBufferIndex++; materialIndices [mat] = lastBufferIndex; materials [lastBufferIndex] = Instantiate <Material> (mat); } else { Debug.LogError("Too many override materials. Max materials supported = " + MAX_MATERIALS_PER_CHUNK); } materialBufferIndex = lastBufferIndex; } vd.materialBufferIndex = materialBufferIndex; } // Compute voxel definition texture indices including rotations bool supportsEmission = vd.renderType.supportsEmission(); vd.textureIndexTop = AddTexture(vd.textureTop, supportsEmission ? vd.textureTopEmission : null, vd.textureTopNRM, vd.textureTopDISP); vd.textureIndexSide = AddTexture(vd.textureSide, supportsEmission ? vd.textureSideEmission : null, vd.textureSideNRM, vd.textureSideDISP); vd.textureIndexBottom = AddTexture(vd.textureBottom, supportsEmission ? vd.textureBottomEmission : null, vd.textureBottomNRM, vd.textureBottomDISP); vd.textureSideIndices = new TextureRotationIndices[4]; if (vd.renderType.numberOfTextures() == 6) { int textureIndexRight = AddTexture(vd.textureRight, supportsEmission ? vd.textureRightEmission : null, vd.textureRightNRM, vd.textureRightDISP); int textureIndexForward = AddTexture(vd.textureForward, supportsEmission ? vd.textureForwardEmission : null, vd.textureForwardNRM, vd.textureForwardDISP); int textureIndexLeft = AddTexture(vd.textureLeft, supportsEmission ? vd.textureLeftEmission : null, vd.textureLeftNRM, vd.textureLeftDISP); // Rotated texture indices. In geometry shaders, lower 12 bits are combined with upper bits to define texture indices (2 texture indices per field) // x = side + forward, y = top + right, z = bottom + left if (effectiveUseGeometryShaders) { vd.textureSideIndices [0] = new TextureRotationIndices { xyzw = new Vector4(vd.textureIndexSide + (textureIndexForward << 12), vd.textureIndexTop + (textureIndexRight << 12), vd.textureIndexBottom + (textureIndexLeft << 12), 0) }; vd.textureSideIndices [1] = new TextureRotationIndices { xyzw = new Vector4(textureIndexRight + (textureIndexLeft << 12), vd.textureIndexTop + (textureIndexForward << 12), vd.textureIndexBottom + (vd.textureIndexSide << 12), 0) }; vd.textureSideIndices [2] = new TextureRotationIndices { xyzw = new Vector4(textureIndexForward + (vd.textureIndexSide << 12), vd.textureIndexTop + (textureIndexLeft << 12), vd.textureIndexBottom + (textureIndexRight << 12), 0) }; vd.textureSideIndices [3] = new TextureRotationIndices { xyzw = new Vector4(textureIndexLeft + (textureIndexLeft << 12), vd.textureIndexTop + (vd.textureIndexSide << 12), vd.textureIndexBottom + (textureIndexForward << 12), 0) }; } else { vd.textureSideIndices [0] = new TextureRotationIndices { forward = textureIndexForward, right = textureIndexRight, back = vd.textureIndexSide, left = textureIndexLeft }; vd.textureSideIndices [1] = new TextureRotationIndices { forward = textureIndexLeft, right = textureIndexForward, back = textureIndexRight, left = textureIndexForward }; vd.textureSideIndices [2] = new TextureRotationIndices { forward = vd.textureIndexSide, right = textureIndexLeft, back = textureIndexForward, left = textureIndexRight }; vd.textureSideIndices [3] = new TextureRotationIndices { forward = textureIndexRight, right = vd.textureIndexSide, back = textureIndexLeft, left = vd.textureIndexSide }; } } else { if (effectiveUseGeometryShaders) { vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices { xyzw = new Vector4(vd.textureIndexSide + (vd.textureIndexSide << 12), vd.textureIndexTop + (vd.textureIndexSide << 12), vd.textureIndexBottom + (vd.textureIndexSide << 12), 0) }; } else { vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices { forward = vd.textureIndexSide, right = vd.textureIndexSide, back = vd.textureIndexSide, left = vd.textureIndexSide }; } } if (vd.renderType == RenderType.CutoutCross && vd.sampleColor.a == 0) { AnalyzeGrassTexture(vd, vd.textureSide); } else { if (vd.textureIndexSide > 0) { Color32[] colors = worldTextures [vd.textureIndexSide].colorsAndEmission; vd.sampleColor = colors [Random.Range(0, colors.Length)]; } } GetVoxelThumbnails(vd); }
void AddVoxelTextures(VoxelDefinition vd) { if (!AppendVoxelDefinition(vd)) { return; } // Autofix certain non supported properties if (vd.navigatable) { vd.navigatable = vd.renderType.supportsNavigation(); } // Check if custom model has collider vd.prefabUsesCollider = false; if (vd.renderType == RenderType.Custom) { if (vd.model == null) { // custom voxel is missing model so we assign a default cube vd.model = GetDefaultVoxelPrefab(); } vd.prefab = vd.model; if (vd.model != null) { if (vd.prefabMaterial != CustomVoxelMaterial.PrefabMaterial) { Material instancingMat = null; switch (vd.prefabMaterial) { case CustomVoxelMaterial.VertexLit: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model VertexLit"); break; case CustomVoxelMaterial.Texture: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture"); break; case CustomVoxelMaterial.TextureAlpha: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Alpha"); break; case CustomVoxelMaterial.TextureAlphaDoubleSided: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Alpha Double Sided"); break; case CustomVoxelMaterial.TextureTriplanar: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Triplanar"); break; case CustomVoxelMaterial.TextureCutout: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Cutout"); break; } if (instancingMat != null) { instancingMat = Instantiate <Material> (instancingMat); vd.prefab = Instantiate <GameObject> (vd.model); vd.prefab.SetActive(false); vd.prefab.transform.SetParent(transform, false); Renderer [] rr = vd.prefab.GetComponentsInChildren <Renderer> (); for (int k = 0; k < rr.Length; k++) { Material refMat = rr [k].sharedMaterial; if (refMat != null) { if (refMat.HasProperty("_Color") && instancingMat.HasProperty("_Color")) { instancingMat.SetColor("_Color", refMat.GetColor("_Color")); } if (refMat.HasProperty("_MainTex") && instancingMat.HasProperty("_MainTex")) { instancingMat.SetTexture("_MainTex", refMat.GetTexture("_MainTex")); } if (refMat.HasProperty("_BumpMap") && instancingMat.HasProperty("_BumpMap")) { instancingMat.SetTexture("_BumpMap", refMat.GetTexture("_BumpMap")); } } rr [k].sharedMaterial = instancingMat; } } } // annotate if model has collider Collider prefabCollider = vd.prefab.GetComponentInChildren <Collider> (); bool hasPrefabCollider = prefabCollider != null; if (vd.gpuInstancing) { if (vd.createGameObject) { vd.prefabUsesCollider = hasPrefabCollider; } } else { vd.prefabUsesCollider = hasPrefabCollider; } if (hasPrefabCollider && applicationIsPlaying && prefabCollider is BoxCollider) { StartCoroutine(ComputePrefabBoxColliderBounds(vd)); } } if (vd.textureSide == null) { // assign default texture sample for inventory icons Material modelMaterial = vd.material; if (modelMaterial != null && modelMaterial.mainTexture != null && modelMaterial.mainTexture is Texture2D) { vd.icon = (Texture2D)modelMaterial.mainTexture; } } } // Assign default material Material mat = vd.GetOverrideMaterial(); if (mat == null) { switch (vd.renderType) { case RenderType.Opaque: case RenderType.Opaque6tex: vd.materialBufferIndex = INDICES_BUFFER_OPAQUE; break; case RenderType.OpaqueAnimated: vd.materialBufferIndex = INDICES_BUFFER_OPANIM; break; case RenderType.Cutout: vd.materialBufferIndex = INDICES_BUFFER_CUTOUT; break; case RenderType.CutoutCross: vd.materialBufferIndex = INDICES_BUFFER_CUTXSS; break; case RenderType.Water: vd.materialBufferIndex = INDICES_BUFFER_WATER; break; case RenderType.Transp6tex: vd.materialBufferIndex = INDICES_BUFFER_TRANSP; break; case RenderType.Cloud: vd.materialBufferIndex = INDICES_BUFFER_CLOUD; break; case RenderType.OpaqueNoAO: vd.materialBufferIndex = INDICES_BUFFER_OPNOAO; break; } } else { // Assign material index int materialBufferIndex; if (!materialIndices.TryGetValue(mat, out materialBufferIndex)) { if (lastBufferIndex < renderingMaterials.Length - 1) { lastBufferIndex++; materialIndices [mat] = lastBufferIndex; if (vd.texturesByMaterial) { renderingMaterials [lastBufferIndex].material = mat; renderingMaterials [lastBufferIndex].usesTextureArray = false; } else { renderingMaterials [lastBufferIndex].material = Instantiate <Material> (mat); renderingMaterials [lastBufferIndex].usesTextureArray = true; } } else { Debug.LogError("Too many override materials. Max materials supported = " + MAX_MATERIALS_PER_CHUNK); } materialBufferIndex = lastBufferIndex; } vd.materialBufferIndex = materialBufferIndex; } // Compute voxel definition texture indices including rotations bool supportsEmission = vd.renderType.supportsEmission(); bool animated = vd.renderType.supportsTextureAnimation(); vd.textureIndexTop = AddTexture(vd.textureTop, supportsEmission ? vd.textureTopEmission : null, vd.textureTopNRM, vd.textureTopDISP, !animated); if (animated) { for (int k = 0; k < vd.animationTextures.Length; k++) { AddTexture(vd.animationTextures [k].textureTop != null ? vd.animationTextures [k].textureTop : vd.textureTop, null, null, null, false); } } vd.textureIndexSide = AddTexture(vd.textureSide, supportsEmission ? vd.textureSideEmission : null, vd.textureSideNRM, vd.textureSideDISP, !animated); if (animated) { for (int k = 0; k < vd.animationTextures.Length; k++) { AddTexture(vd.animationTextures [k].textureSide != null ? vd.animationTextures [k].textureSide : vd.textureSide, null, null, null, false); } } vd.textureIndexBottom = AddTexture(vd.textureBottom, supportsEmission ? vd.textureBottomEmission : null, vd.textureBottomNRM, vd.textureBottomDISP, !animated); if (animated) { for (int k = 0; k < vd.animationTextures.Length; k++) { AddTexture(vd.animationTextures [k].textureBottom != null ? vd.animationTextures [k].textureBottom : vd.textureBottom, null, null, null, false); } } if (vd.textureSideIndices == null || vd.textureSideIndices.Length != 4) { vd.textureSideIndices = new TextureRotationIndices [4]; } if (vd.renderType.numberOfTextures() == 6) { int textureIndexRight = vd.textureIndexRight = AddTexture(vd.textureRight, supportsEmission ? vd.textureRightEmission : null, vd.textureRightNRM, vd.textureRightDISP); int textureIndexForward = vd.textureIndexForward = AddTexture(vd.textureForward, supportsEmission ? vd.textureForwardEmission : null, vd.textureForwardNRM, vd.textureForwardDISP); int textureIndexLeft = vd.textureIndexLeft = AddTexture(vd.textureLeft, supportsEmission ? vd.textureLeftEmission : null, vd.textureLeftNRM, vd.textureLeftDISP); vd.textureSideIndices [0] = new TextureRotationIndices { forward = textureIndexForward, right = textureIndexRight, back = vd.textureIndexSide, left = textureIndexLeft }; vd.textureSideIndices [1] = new TextureRotationIndices { forward = textureIndexLeft, right = textureIndexForward, back = textureIndexRight, left = vd.textureIndexSide }; vd.textureSideIndices [2] = new TextureRotationIndices { forward = vd.textureIndexSide, right = textureIndexLeft, back = textureIndexForward, left = textureIndexRight }; vd.textureSideIndices [3] = new TextureRotationIndices { forward = textureIndexRight, right = vd.textureIndexSide, back = textureIndexLeft, left = textureIndexForward }; } else { vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices { forward = vd.textureIndexSide, right = vd.textureIndexSide, back = vd.textureIndexSide, left = vd.textureIndexSide }; } if (vd.renderType == RenderType.CutoutCross && vd.sampleColor.a == 0) { AnalyzeGrassTexture(vd, vd.textureSample != null ? vd.textureSample : vd.textureSide); } else { if (vd.textureSample != null) { Color32 [] colors = vd.textureSample.GetPixels32(); vd.sampleColor = colors [Random.Range(0, colors.Length)]; } else if (vd.textureIndexSide > 0) { Color32 [] colors = worldTextures [vd.textureIndexSide].colorsAndEmission; vd.sampleColor = colors [Random.Range(0, colors.Length)]; } } GetVoxelThumbnails(vd); }