XRoom_Unity/Assets/VR Classroom/RenderTextureSender.cs
2025-05-31 10:20:20 +03:30

196 lines
5.9 KiB
C#

using System.Collections.Generic;
using Fusion;
using UnityEngine;
public class RenderTextureSender : NetworkBehaviour
{
public Camera targetCamera;
public GameObject OtherWhiteBoard;
private bool isInitialized = false;
private const int MaxPayloadSize = 450; // حداکثر اندازه چانک
private Texture2D previousTexture; // ذخیره تکسچر قبلی برای مقایسه
public GameObject back;
private float resendTimer;
private List<byte> textureDataList = new List<byte>(); // برای ذخیره داده‌های چانک‌ها
public override void Spawned()
{
base.Spawned();
if (Object == null)
{
Debug.LogError("[Photon Fusion] NetworkObject مقداردهی نشده است!");
return;
}
isInitialized = true;
Debug.Log("[Photon Fusion] RenderTextureSender Initialized.");
}
private void Start()
{
if (targetCamera == null)
{
Debug.LogError("[Photon Fusion] Target Camera مقداردهی نشده است!");
}
resendTimer = Time.time;
}
public int timerLoad = 60;
private void Update()
{
if (isInitialized && Time.time > resendTimer)
{
resendTimer = Time.time + timerLoad;
SendRenderTexture();
Remove();
}
}
public void Remove()
{
if (back != null)
{
back.gameObject.SetActive(false);
}
}
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
public void RPC_SendRenderTexture(byte[] textureData, int chunkIndex, int totalChunks)
{
Debug.Log("Received Chunk: " + chunkIndex + "/" + totalChunks);
if (!isInitialized)
{
Debug.LogError("[Photon Fusion] هنوز مقداردهی نشده است!");
return;
}
textureDataList.AddRange(textureData);
if (chunkIndex == totalChunks - 1) // دریافت کامل چانک‌ها
{
Texture2D receivedTexture = new Texture2D(2, 2);
receivedTexture.LoadImage(textureDataList.ToArray());
ApplyTexture(receivedTexture);
textureDataList.Clear();
}
}
public void SendRenderTexture()
{
if (Object == null)
{
Debug.LogError("[Photon Fusion] NetworkObject مقداردهی نشده است!");
return;
}
//if (!Object.HasInputAuthority)
{
// Debug.LogWarning("[Photon Fusion] شما دسترسی لازم برای ارسال RPC ندارید!");
// return;
}
if (targetCamera == null || targetCamera.targetTexture == null)
{
Debug.LogError("[Photon Fusion] Target Camera یا RenderTexture مقداردهی نشده است!");
return;
}
Texture2D currentTexture = GetTextureFromRenderTexture(targetCamera.targetTexture);
if (previousTexture != null && AreTexturesEqual(previousTexture, currentTexture))
{
return; // عدم ارسال در صورت نبود تغییرات
}
previousTexture = currentTexture;
byte[] textureData = RenderTextureUtils.RenderTextureToByteArray(targetCamera.targetTexture);
int totalChunks = Mathf.CeilToInt(textureData.Length / (float)MaxPayloadSize);
for (int i = 0; i < totalChunks; i++)
{
int chunkSize = Mathf.Min(MaxPayloadSize, textureData.Length - i * MaxPayloadSize);
byte[] chunkData = new byte[chunkSize];
System.Array.Copy(textureData, i * MaxPayloadSize, chunkData, 0, chunkSize);
RPC_SendRenderTexture(chunkData, i, totalChunks);
}
}
private void ApplyTexture(Texture2D texture)
{
if (OtherWhiteBoard == null)
{
OtherWhiteBoard = GameObject.FindGameObjectWithTag("whiteboard");
}
if (OtherWhiteBoard == null)
{
Debug.LogError("[Photon Fusion] OtherWhiteBoard مقداردهی نشده است!");
return;
}
Renderer renderer = OtherWhiteBoard.GetComponent<Renderer>();
if (renderer != null)
{
if(!Runner.IsServer)
renderer.GetComponent<MeshRenderer>().enabled = true;
renderer.material.mainTexture = texture;
}
}
private Texture2D GetTextureFromRenderTexture(RenderTexture renderTexture)
{
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
RenderTexture.active = renderTexture;
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture.Apply();
RenderTexture.active = null;
return texture;
}
private bool AreTexturesEqual(Texture2D texture1, Texture2D texture2)
{
if (texture1.width != texture2.width || texture1.height != texture2.height)
{
return false;
}
Color[] pixels1 = texture1.GetPixels();
Color[] pixels2 = texture2.GetPixels();
for (int i = 0; i < pixels1.Length; i++)
{
if (pixels1[i] != pixels2[i])
{
return false;
}
}
return true;
}
}
public static class RenderTextureUtils
{
public static byte[] RenderTextureToByteArray(RenderTexture renderTexture)
{
if (renderTexture == null)
{
Debug.LogError("[RenderTextureUtils] RenderTexture مقداردهی نشده است!");
return null;
}
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
RenderTexture.active = renderTexture;
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture.Apply();
RenderTexture.active = null;
return texture.EncodeToJPG(75);
}
}