从C ++本机插件更新Vector3数组 [英] Update Vector3 array from C++ native plugin

查看:100
本文介绍了从C ++本机插件更新Vector3数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Marshal.Copy()方法仅支持几种数组类型.现在我只知道如何从IntPtr(指向C ++代码中的float数组)复制到float[].

Marshal.Copy() Method only supports a few array types. Now I only know how to copy from IntPtr(pointing to a float array from C++ code) to float[].

IntPtr pvertices = GetVerticesFromCPP();
float[] vertices = new float[nVertices * 3];
Marshal.Copy(pvertices, vertices, 0, nVertices * 3);

但是我真正想要的是UnityEngine.Vector3[].

But what I really want is a UnityEngine.Vector3[].

我需要手动将float[]转换为UnityEngine.Vector3[]吗?还是有一种更简单,更快捷的方法可以直接做到这一点?

Do I need to manually convert float[] to UnityEngine.Vector3[]? Or is there a simpler and faster way that directly do this?

推荐答案

我需要手动将float []转换为UnityEngine.Vector3 []吗?或者是 有没有更简单,更快捷的方法可以直接做到这一点?

Do I need to manually convert float[] to UnityEngine.Vector3[]? Or is there a simpler and faster way that directly do this?

是的,您必须手动执行此操作,但是有更好的方法来执行此操作.

Yes, you have to do that manually but there is a better way to do this.

我将假定您需要在本机端修改Vector3然后返回结果.无需为此使用float数组.只需在C ++端创建一个Vector3结构,然后使用指针在C ++和C#之间传递它即可. 请勿从C ++返回Vector3数组,请在C#端创建它,然后将其传递给C ++函数以修改并将更改应用于参数.

I will assume that you need to modify a Vector3 on the native side then return the result. There is no need to use float array for this. Just create a Vector3 struct on the C++ side then use pointer to pass it between C++ and C#. Do not return the Vector3 array from C++, create it on the C# side, then pass it to the C++ function to modify and apply the changes to the argument.

C ++:

这要求您启用 Unity中的不安全关键字.

This requires that you enable the unsafe keyword in Unity.

struct Vector3
{
     float x;
     float y;
     float z;
};

然后执行功能:

extern "C" void UpdateVectorArray(Vector3* vecArray, int vecSize)
{
    for(int i = 0; i < vecSize; ++i)
    {
        //Simply modify each Vector reference
        Vector3 &vec = vecArray[i];
        vec.x = 11;
        vec.y = 20;
        vec.z = 55;
    }
}

C#:

[DllImport("Plugin Name")]
static unsafe extern void UpdateVectorArray(Vector3* vecArray, int vecSize);


void UpdateVectorArray(Vector3[] vecArray)
{
    unsafe
    {
        //Pin array then send to C++
        fixed (Vector3* vecPtr = vecArray)
        {
            UpdateVectorArray(vecPtr, vecArray.Length);
        }
    }
}

用法:

从模型获取顶点,发送到C ++并对其进行修改,然后重新分配修改后的网格:

Get vertices from model, send to C++ and modify it the re-assign the modified mesh:

void Start()
{
    Mesh mesh = GetComponent<MeshFilter>().mesh;

    Vector3[] vertices = mesh.vertices;
    UpdateVectorArray(vertices);

    //Re-assign the modified mesh
    mesh.vertices = vertices;
    mesh.RecalculateBounds();
}


为避免在Unity中使用unsafe关键字,请使用[In, Out]属性.


To avoid using the unsafe keyword in Unity use the [In, Out] attribute.

[DllImport("Plugin Name")]
static extern void UpdateVectorArray([In, Out] Vector3[] vecArray, int vecSize);

void Start()
{
    Mesh mesh = GetComponent<MeshFilter>().mesh;

    Vector3[] vertices = mesh.vertices;
    UpdateVectorArray(vertices, vertices.Length);

    mesh.vertices = vertices;
    mesh.RecalculateBounds();
}

C ++方面仍然相同.您还可以使用 GCHandle 固定数组,并避免使用unsafe关键字,但是unsafe关键字解决方案是更好更快.

The C++ side remains the-same. You can also use the GCHandle to pin the array and avoid using the unsafe keyword but the unsafe keyword solution is better and faster.

这篇关于从C ++本机插件更新Vector3数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆