public void PaintPixelsInRam(PaintCommand.UV command) { Stroke stroke = command.Stroke; float brushAlpha = command.strokeAlphaPortion; TextureMeta image = command.TextureData; Brush bc = command.Brush; var volume = image.texture2D.GetVolumeTextureData(); if (!volume) { return; } bc.brush3DRadius = Mathf.Min(BrushScaleMaxForCpu(volume), bc.brush3DRadius); var volumeScale = volume.size; var pos = (stroke.posFrom - volume.transform.position) / volumeScale + 0.5f * Vector3.one; var height = volume.Height; var texWidth = image.width; BlitFunctions.brAlpha = brushAlpha; bc.PrepareCpuBlit(image); BlitFunctions.half = bc.Size(true) / volumeScale; var pixels = image.Pixels; var iHalf = (int)(BlitFunctions.half - 0.5f); var smooth = bc.GetBrushType(true) != BrushTypes.Pixel.Inst; if (smooth) { iHalf += 1; } BlitFunctions.alphaMode = BlitFunctions.SphereAlpha; var sliceWidth = texWidth / volume.hSlices; var hw = sliceWidth / 2; var y = (int)pos.y; var z = (int)(pos.z + hw); var x = (int)(pos.x + hw); for (BlitFunctions.y = -iHalf; BlitFunctions.y < iHalf + 1; BlitFunctions.y++) { var h = y + BlitFunctions.y; if (h >= height) { return; } if (h < 0) { continue; } var hy = h / volume.hSlices; var hx = h % volume.hSlices; var hTexIndex = (hy * texWidth + hx) * sliceWidth; for (BlitFunctions.z = -iHalf; BlitFunctions.z < iHalf + 1; BlitFunctions.z++) { var trueZ = z + BlitFunctions.z; if (trueZ < 0 || trueZ >= sliceWidth) { continue; } var yTexIndex = hTexIndex + trueZ * texWidth; for (BlitFunctions.x = -iHalf; BlitFunctions.x < iHalf + 1; BlitFunctions.x++) { if (!BlitFunctions.alphaMode()) { continue; } var trueX = x + BlitFunctions.x; if (trueX < 0 || trueX >= sliceWidth) { continue; } var texIndex = yTexIndex + trueX; BlitFunctions.blitMode(ref pixels[texIndex]); } } } }
public bool PaintTexture2D(PaintCommand.UV command) { Stroke stroke = command.Stroke; float brushAlpha = command.strokeAlphaPortion; TextureMeta image = command.TextureData; Brush bc = command.Brush; if (!painter.IsAtlased()) { return(false); } var uvCoords = stroke.uvFrom; var atlasedSection = GetAtlasedSection(); sectorSize = image.width / atlasRows; atlasSector.From(atlasedSection * sectorSize); BlitFunctions.brAlpha = brushAlpha; BlitFunctions.half = (bc.Size(false)) / 2; var iHalf = Mathf.FloorToInt(BlitFunctions.half - 0.5f); var smooth = bc.GetBrushType(true) != BrushTypes.Pixel.Inst; if (smooth) { BlitFunctions.alphaMode = BlitFunctions.CircleAlpha; } else { BlitFunctions.alphaMode = BlitFunctions.NoAlpha; } BlitFunctions.blitMode = bc.GetBlitMode(true).BlitFunctionTex2D(image); if (smooth) { iHalf += 1; } BlitFunctions.alpha = 1; BlitFunctions.Set(bc.mask); BlitFunctions.cSrc = bc.Color; var tmp = image.UvToPixelNumber(uvCoords); var fromX = tmp.x - iHalf; tmp.y -= iHalf; var pixels = image.Pixels; for (BlitFunctions.y = -iHalf; BlitFunctions.y < iHalf + 1; BlitFunctions.y++) { tmp.x = fromX; for (BlitFunctions.x = -iHalf; BlitFunctions.x < iHalf + 1; BlitFunctions.x++) { if (BlitFunctions.alphaMode()) { var sx = tmp.x - atlasSector.x; var sy = tmp.y - atlasSector.y; sx %= sectorSize; if (sx < 0) { sx += sectorSize; } sy %= sectorSize; if (sy < 0) { sy += sectorSize; } BlitFunctions.blitMode(ref pixels[((atlasSector.y + sy)) * image.width + (atlasSector.x + sx)]); } tmp.x += 1; } tmp.y += 1; } return(true); }
private void Paint() { RaycastHit hit; for (var i = 0; i < shoots; i++) { if (Physics.Raycast(new Ray(transform.position, transform.forward + transform.right * Random.Range(-spread, spread) + transform.up * Random.Range(-spread, spread)), out hit)) { var receivers = hit.transform.GetComponentsInParent <PaintingReceiver>(); if (receivers.Length == 0) { continue; } int subMesh; var receiver = receivers[0]; // IF FEW SubMeshes if (hit.collider.GetType() == typeof(MeshCollider)) { subMesh = ((MeshCollider)hit.collider).sharedMesh.GetSubMeshNumber(hit.triangleIndex); if (receivers.Length > 1) { var mats = receiver.Renderer.materials; var material = mats[subMesh % mats.Length]; receiver = receivers.FirstOrDefault(r => r.Material == material); } } else { subMesh = receiver.materialIndex; } // ACTUAL PAINTING if (!receiver) { continue; } var tex = receiver.GetTexture(); if (!tex) { continue; } var rendTex = (receiver.texture.GetType() == typeof(RenderTexture)) ? (RenderTexture)receiver.texture : null; // WORLD SPACE BRUSH if (rendTex) { var st = new StrokeVector(hit.point) { unRepeatedUv = hit.collider.GetType() == typeof(MeshCollider) ? (receiver.useTexcoord2 ? hit.textureCoord2 : hit.textureCoord).Floor() : receiver.meshUvOffset, }; switch (receiver.type) { case PaintingReceiver.RendererType.Skinned when receiver.skinnedMeshRenderer: BrushTypes.Sphere.Paint(rendTex, receiver.gameObject, receiver.skinnedMeshRenderer, brush, st, subMesh); break; case PaintingReceiver.RendererType.Regular when receiver.meshFilter: { var mat = receiver.Material; if (mat && mat.IsAtlased()) { BrushTypes.Sphere.PaintAtlased(rendTex, receiver.gameObject, receiver.originalMesh ? receiver.originalMesh : receiver.meshFilter.sharedMesh, brush, st, new List <int> { subMesh }, (int)mat.GetFloat(PainterDataAndConfig.ATLASED_TEXTURES)); } else { BrushTypes.Sphere.Paint(rendTex, receiver.gameObject, receiver.originalMesh ? receiver.originalMesh : receiver.meshFilter.sharedMesh, brush, st, new List <int> { subMesh }); } break; } } } // TEXTURE SPACE BRUSH else if (receiver.texture is Texture2D) { if (hit.collider.GetType() != typeof(MeshCollider)) { Debug.Log("Can't get UV coordinates from a Non-Mesh Collider"); } BlitFunctions.Paint(receiver.useTexcoord2 ? hit.textureCoord2 : hit.textureCoord, 1, (Texture2D)receiver.texture, Vector2.zero, Vector2.one, brush, null); var id = receiver.texture.GetTextureData(); _texturesNeedUpdate.AddIfNew(id); } else { Debug.Log(receiver.gameObject.name + " doesn't have any combination of paintable things setup on his PainterReciver."); } } } }
private void Paint() { RaycastHit hit; for (var i = 0; i < (continious ? 1 : shoots); i++) { if (Physics.Raycast(new Ray(transform.position, transform.forward + (continious ? Vector3.zero : (transform.right * Random.Range(-spread, spread) + transform.up * Random.Range(-spread, spread))) ) , out hit)) { var receivers = hit.transform.GetComponentsInParent <PaintingReceiver>(); if (receivers.Length == 0) { continue; } int subMesh; var receiver = receivers[0]; #region Multiple Submeshes if (hit.collider.GetType() == typeof(MeshCollider)) { subMesh = ((MeshCollider)hit.collider).sharedMesh.GetSubMeshNumber(hit.triangleIndex); if (receivers.Length > 1) { var mats = receiver.Renderer.materials; var material = mats[subMesh % mats.Length]; receiver = receivers.FirstOrDefault(r => r.Material == material); } } else { subMesh = receiver.materialIndex; } #endregion if (!receiver) { continue; } var tex = receiver.GetTexture(); if (!tex) { continue; } var rendTex = (receiver.texture.GetType() == typeof(RenderTexture)) ? (RenderTexture)receiver.texture : null; #region WORLD SPACE BRUSH if (continious) { if (previousTargetForContinious && (receiver != previousTargetForContinious)) { continiousStroke.OnMouseUnPressed(); } previousTargetForContinious = receiver; } if (rendTex) { var st = continious ? continiousStroke : new StrokeVector(hit, receiver.useTexcoord2); st.unRepeatedUv = hit.collider.GetType() == typeof(MeshCollider) ? (receiver.useTexcoord2 ? hit.textureCoord2 : hit.textureCoord).Floor() : receiver.meshUvOffset; if (continious) { st.OnMousePressed(hit, receiver.useTexcoord2); } if (receiver.type == PaintingReceiver.RendererType.Skinned && receiver.skinnedMeshRenderer) { BrushTypes.Sphere.Paint(rendTex, receiver.gameObject, receiver.skinnedMeshRenderer, brush, st, subMesh); } else if (receiver.type == PaintingReceiver.RendererType.Regular && receiver.meshFilter) { if (brush.GetBrushType(false) == BrushTypes.Sphere.Inst) { var mat = receiver.Material; if (mat && mat.IsAtlased()) { BrushTypes.Sphere.PaintAtlased(rendTex, receiver.gameObject, receiver.originalMesh ? receiver.originalMesh : receiver.meshFilter.sharedMesh, brush, st, new List <int> { subMesh }, (int)mat.GetFloat(PainterShaderVariables.ATLASED_TEXTURES)); } else { BrushTypes.Sphere.Paint(rendTex, receiver.gameObject, receiver.originalMesh ? receiver.originalMesh : receiver.meshFilter.sharedMesh, brush, st, new List <int> { subMesh }); } } else { BrushTypes.Normal.Paint(rendTex, brush, st); } break; } } #endregion #region TEXTURE SPACE BRUSH else if (receiver.texture is Texture2D) { if (hit.collider.GetType() != typeof(MeshCollider)) { Debug.Log("Can't get UV coordinates from a Non-Mesh Collider"); } BlitFunctions.Paint(receiver.useTexcoord2 ? hit.textureCoord2 : hit.textureCoord, 1, (Texture2D)receiver.texture, Vector2.zero, Vector2.one, brush, null); var id = receiver.texture.GetTextureMeta(); _texturesNeedUpdate.AddIfNew(id); } #endregion else { Debug.Log(receiver.gameObject.name + " doesn't have any combination of paintable things setup on his PainterReciver."); } } } }