我正在使用Replicate API尝试在Unity中获取点云。我最后使用API返回一个JSON文件,我非常确定它返回的是每个点位置的vector3
。然而,当我把它转换成一个vector 3时,所有的值都变得不正常,每个数字都像6.852349e-43,甚至一些“NaN”,当在API上它们看起来都是小于0的值时。
这是他们在副本页面上的样子,
"coords": [
[
-0.039118800312280655,
-0.25740715861320496,
0.28050559759140015
],
[
0.13176295161247253,
0.23972494900226593,
-0.06013050675392151
],
然而,当我在Unity中将它们转换为vector3
时,它们会像这样返回,x1c 0d1x我假设我不应该将它们转换为vector3
?Replicate的页面上说“坐标”是一个[N x 3]数组(X,Y,Z)点坐标”,经过广泛的谷歌搜索,我不知道NX 3是什么意思。我尝试了float[,]
、float[,,]
和float[][]
而不是vector3
,但vector3
是唯一一个从JSON文件中正确分配的(使用JsonUtility.FromJson
)
这是我调用API的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using SimpleJSON;
public class Prompt
{
public string prompt;
}
public class PostResponse
{
public string completed_at;
public string created_at;
public string error;
public string id;
public Prompt input;
public string[] logs;
public string metrics;
public Output output;
public string started_at;
public string status;
public string version;
}
public class ReplicateAPI : MonoBehaviour
{
private string API_ENDPOINT = "https://api.replicate.com/v1/predictions";
private string REPLICATE_API_TOKEN = "r8_DhOE6C7LuA7edPvLh7Io0ukwbmXCLEY450vc3";
[SerializeField] PointEResponse response;
public string prompt = "dog";
[SerializeField] Material material;
[SerializeField] MeshFilter meshFilter;
private void Start()
{
StartCoroutine(Predict());
}
IEnumerator Predict()
{
string requestData = $@"{{
""version"": ""1a4da7adf0bc84cd786c1df41c02db3097d899f5c159f5fd5814a11117bdf02b"",
""input"": {{
""prompt"": ""{prompt}"",
""output_format"": ""json_file""
}}
}}";
UnityWebRequest request = UnityWebRequest.Put(API_ENDPOINT, requestData);
request.method = "POST";
request.SetRequestHeader("Authorization", "Token " + REPLICATE_API_TOKEN);
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError("Error " + request.responseCode + ": " + request.error);
StartCoroutine(Predict());
}
else
{
Debug.Log(request.downloadHandler.text);
PostResponse response = JsonUtility.FromJson<PostResponse>(request.downloadHandler.text);
StartCoroutine(GetResult(response.id));
}
}
IEnumerator GetResult(string id)
{
yield return new WaitForSeconds(5);
UnityWebRequest request = UnityWebRequest.Get(API_ENDPOINT + "/" + id);
request.SetRequestHeader("Authorization", "Token " + REPLICATE_API_TOKEN);
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError("Error " + request.responseCode + ": " + request.error);
yield break;
}
else
{
response = JsonUtility.FromJson<PointEResponse>(request.downloadHandler.text);
Debug.Log(request.downloadHandler.text);
}
if (response.status != "succeeded") StartCoroutine(GetResult(id));
else
{
if (response.output.json_file.colors != null && response.output.json_file.colors.Length > 0)
{
for (int i = 0; i < response.output.json_file.colors.Length; i++)
{
GameObject g = GameObject.CreatePrimitive(PrimitiveType.Sphere);
g.transform.localScale = Vector3.one / 100;
g.transform.position = new Vector3(response.output.json_file.coords[i].x, response.output.json_file.coords[i].y, response.output.json_file.coords[i].z);
Material m = new Material(material);
m.color = new Color(response.output.json_file.colors[i].x, response.output.json_file.colors[i].y, response.output.json_file.colors[i].z);
g.GetComponent<MeshRenderer>().material = m;
}
}
else
{
StartCoroutine(GetResult(id));
}
}
}
}
“响应”类看起来像这样,
using System;
using UnityEngine;
[Serializable]
public class PointEResponse
{
public string id;
public string version;
public Urls urls;
public DateTime created_at;
public DateTime started_at;
public DateTime completed_at;
public string source;
public string status;
public Prompt input;
public Output output;
public object error;
public string[] logs;
public Metrics metrics;
}
[Serializable]
public class Output
{
public JsonFile json_file;
}
[Serializable]
public class JsonFile
{
public Vector3[] coords;
public Vector3[] colors;
}
public class Urls
{
public string get;
public string cancel;
}
public class Metrics
{
public float predict_time;
}
其中输出包含坐标和每个坐标的颜色。我假设我不应该将这些转换为Vector 3,但我已经尝试了我所知道的所有其他方法,这是唯一一个甚至返回任何形式的方法。
如何解决此问题?
1条答案
按热度按时间mtb9vblg1#
您在这里得到的JSON不会直接匹配
Vector3
。例如,
Vector3
不能直接进行JSON(反)序列化。意味着你得到的东西看起来像
如果以及如何将其在内存中布局成
Vector3
结构体,我猜是黑魔法。然而,内置的
JsonUtility
/Unity的序列化器也不支持这种复杂的集合!您可能需要第三方库,例如。
Newtonsoft Json.NET
,作为package via Package Manager提供如果你用它来代替,你会去例如。
然后离开
顺便说一句,因为
Vector3
是一个结构体,你可以简单地做