unity 调用c++ dll同时将unity的值传给c++

news2024/11/23 11:57:09

最近因为项目的需要,实现了将C++工程生成dll在unity中调用,但同时发现如果能让unity中值实时的传给c++则就完美了,而不只是把c++计算的结果给unity。

通过验证是可行的。

C++ 生成dll导出关键部分

// SPDX-License-Identifier: MIT
// Copyright (c) 2021 Manuel Stoiber, German Aerospace Center (DLR)

//#include <srt3d/azure_kinect_camera.h>
#include <srt3d/my_camera.h>
#include <srt3d/camera.h>
#include <srt3d/body.h>
#include <srt3d/common.h>
#include <srt3d/normal_viewer.h>
#include <srt3d/occlusion_renderer.h>
#include <srt3d/region_modality.h>
#include <srt3d/renderer_geometry.h>
#include <srt3d/tracker.h>
#include <cmath>
#include <Eigen/Geometry>
#include <filesystem>
#include <memory>
#include <string>
#include <Windows.h>

//Generate body1 template view 2562 of 2562

//global variables
const char* modelName = "";

const std::filesystem::path model_directory{ "D:\\sourcecode\\STR3D\\rbotdataset\\" };

constexpr bool kSaveViewerImage = false;
const std::filesystem::path viewer_save_directory{ "D:\\sourcecode\\STR3D\\SRT3D\\images\\" };

 Set up tracker and renderer geometry
auto tracker_ptr{ std::make_shared<srt3d::Tracker>("tracker") };
auto renderer_geometry_ptr{ std::make_shared<srt3d::RendererGeometry>("renderer geometry") };

 Set up camera

auto camera_ptr{ std::make_shared < srt3d::MyCamera>("RGB") };
 Set up viewers

auto viewer_ptr{ std::make_shared<srt3d::NormalViewer>("viewer", camera_ptr, renderer_geometry_ptr) };


 Set up body1 (change accordingly)
//const std::filesystem::path body1_geometry_path{ "D:\\sourcecode\\STR3D\\rbotdataset\\motorpart01.obj" };
const std::filesystem::path body1_geometry_path{ "D:\\sourcecode\\STR3D\\rbotdataset\\duck.obj" };

srt3d::Transform3fA body1_geometry2body_pose{ Eigen::Translation3f(0.0f, 0.0f, 0.0f) };
srt3d::Transform3fA body1_world2body_pose;
srt3d::Transform3fA realtime_myObj2world_pose;


auto body1_ptr{ std::make_shared<srt3d::Body>("body1", body1_geometry_path,
											0.001f, true, false, 0.3f,
											 body1_geometry2body_pose, 1) };

float location[7] = { 0,0, 0, 0,0, 0, 0 };

exe程序
extern "C" __declspec(dllexport)
void main()
{

	body1_world2body_pose.matrix() <<
		1.0f, 0.0f, 0.0f, 0.095f,
		0.0f, 1.0f, 0.0f, 0.1f,
		0.0f, 0.0f, 1.0f, -0.4f,
		0.0f, 0.0f, 0.0f, 1.0f;
	tracker_ptr->AddViewer(viewer_ptr);

	if (kSaveViewerImage) viewer_ptr->StartSavingImages(viewer_save_directory);


	//body1_ptr->set_body2world_pose(body1_world2body_pose);
	body1_ptr->set_world2body_pose(body1_world2body_pose);//原论文code
	renderer_geometry_ptr->AddBody(body1_ptr);


	// Set up model body 1
	//auto body1_model_ptr{ std::make_shared<srt3d::Model>("body1_model", body1_ptr, model_directory, "motorpart01_model.bin") };
	auto body1_model_ptr{ std::make_shared<srt3d::Model>("body1_model", body1_ptr, model_directory, "duck.bin") };

	// Set up region modality body 1
	auto body1_region_modality_ptr{ std::make_shared<srt3d::RegionModality>(
		"body1_region_modality", body1_ptr, body1_model_ptr, camera_ptr) };
	tracker_ptr->AddRegionModality(body1_region_modality_ptr);

	// Set up occlusion renderer
	auto occlusion_renderer_ptr{ std::make_shared<srt3d::OcclusionRenderer>(
		"occlusion_renderer", renderer_geometry_ptr, camera_ptr) };
	body1_region_modality_ptr->UseOcclusionHandling(occlusion_renderer_ptr);

	 Start tracking
	tracker_ptr->SetUpTracker();
	//tracker_ptr->StartTracker(false);
	//float pos_value[3] = {1., 2.8, 2.33};
	//tracker_ptr->StartTracker(false, pos_value);
	//tracker_ptr->StartTracker(false, body1_ptr, &a);
	// 
	if (!tracker_ptr->set_up()) {
		std::cerr << "Set up tracker " << tracker_ptr->set_name() << " first" << std::endl;
		return;
	}
	tracker_ptr->set_start_tracking(false);

}


//将旋转矩阵转化为四元数
Eigen::Quaterniond Matrix2Quaternion(Eigen::Matrix<float, 4, 4> matrixofBody)
{

	Eigen::Matrix<float, 4, 4> matrix_body2world_pose;
	//Eigen::Matrix<float, 3, 3> matrix_rotation;
	Eigen::Matrix3d matrix_rotation;

	//Eigen::Quaterniond matrix_quarternion;

	matrix_body2world_pose = matrixofBody;
	//matrix_body2world_pose = body1_ptr->body2world_pose().matrix();

	//body1_ptr->geometry2world_pose().matrix();
	//for (size_t i = 0; i < 4; i++)
	//{
	//	for (size_t j = 0; j < 4; j++)
	//	{
	//		std::cout << matrix_body2world_pose(i, j) << "\t";
	//	}

	//}

	//取出旋转矩阵
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 3; j++)
		{
			matrix_rotation(i, j) = matrix_body2world_pose(i, j);
		}
	}

	//std::cout << "---------------matrix_quarternion-----------------" << std::endl;
	std::cout << matrix_quarternion << std::endl;
	//std::cout << matrix_quarternion.x() << "\t" <<matrix_quarternion.y() << "\t"  
	//	<< matrix_quarternion.z() << "\t" << matrix_quarternion.z() << "\t" << std::endl;

	return Eigen::Quaterniond(matrix_rotation);
}

Eigen::Quaterniond matrix_quarternion;
Eigen::Matrix<float, 4, 4> matrix_body2world_pose;
extern "C" __declspec(dllexport)
int start_track(int iteration, float* pos_array, bool* update, float x, float y, float z, float w, float pos_x, float pos_y, float pos_z)
//int start_track(int iteration, float* pos_array, bool* update, float pos_z)

{
	/// <summary>
/// For unity dll test
/// </summary>
/// <param name="pos_array"></param>
/// <returns></returns>

		if (tracker_ptr->get_start_tracking())
		{
			if (!tracker_ptr->StartRegionModalities())
			{
				return -1;
			}
			tracker_ptr->set_tracking_started(true);
			tracker_ptr->set_start_tracking(false);

			//std::cout << "StartRegionModalities" << std::endl;



		}
		if (tracker_ptr->get_tracking_started())
		{
			//std::cout << "--------------------------------" << std::endl;
			//std::cout << body1_ptr->body2world_pose().matrix() << std::endl;

			//当物体追踪后实时更新将我们的旋转和平移传给unity
			matrix_body2world_pose = body1_ptr->body2world_pose().matrix();
			matrix_quarternion = Matrix2Quaternion(matrix_body2world_pose);


			//右手坐标转化为左手坐标 x,z取反
			保存表示旋转的四元数和平移的值
			float location[7] = { -matrix_quarternion.x(), matrix_quarternion.y(), -matrix_quarternion.z(), matrix_quarternion.w(),
									matrix_body2world_pose(0, 3), -matrix_body2world_pose(1, 3),matrix_body2world_pose(2, 3) };
			memcpy(pos_array, location, sizeof(float) * 7);

			std::cout << "---------------------translation-----------------------------" << std::endl;
			std::cout << matrix_body2world_pose(0, 3) << "\t" << matrix_body2world_pose(1, 3) << "\t" << matrix_body2world_pose(2, 3) << std::endl;
			

			//控制unity3d 进程的退出
			int update_is[2] = { tracker_ptr->get_update(), 0 };
			memcpy(update, update_is, sizeof(int)*2);


			if (!tracker_ptr->ExecuteTrackingCycle(iteration))
			{
				std::cout << "ExecuteTrackingCycle--break" << std::endl;
				int update_is[2] = { tracker_ptr->get_update(), 2 };
				memcpy(update, update_is, sizeof(int) * 2);
				return -1;
			}
		}
		else
		{
			//传unity物体最初的位置
			//程序开始后将初始化的旋转和平移传给unity
			if (!tracker_ptr->get_update())
			{

				matrix_body2world_pose = body1_ptr->body2world_pose().matrix();
				matrix_quarternion = Matrix2Quaternion(matrix_body2world_pose);
				float location[7] = { -matrix_quarternion.x(), matrix_quarternion.y(), -matrix_quarternion.z(), matrix_quarternion.w(),
						  matrix_body2world_pose(0, 3), -matrix_body2world_pose(1, 3),matrix_body2world_pose(2, 3) };
				memcpy(pos_array, location, sizeof(float) * 7);

			}
			else
			{

				
				int update_is[2] = { tracker_ptr->get_update(), 1 };
				memcpy(update, update_is, sizeof(int) * 2);  //控制unity3d 进程的退出

				接收unity中的物体位姿
				Eigen::Quaterniond quat_u3d(w, x, y, z);

				Eigen::Matrix3d rotation_matrix = quat_u3d.matrix();

				for (size_t i = 0; i < 3; i++)
				{
					for (size_t j = 0; j < 3; j++)
					{
						body1_world2body_pose.matrix()(i, j) = rotation_matrix.matrix()(i, j);
					}
				}

				body1_world2body_pose.matrix()(0, 3) = pos_x;
				body1_world2body_pose.matrix()(1, 3) = pos_y;
				body1_world2body_pose.matrix()(2, 3) = pos_z;

				body1_world2body_pose.matrix()(3, 0) = 0;
				body1_world2body_pose.matrix()(3, 1) = 0;
				body1_world2body_pose.matrix()(3, 2) = 0;
				body1_world2body_pose.matrix()(3, 3) = 1;

				body1_ptr->set_body2world_pose(body1_world2body_pose);
			}


			if (!tracker_ptr->ExecuteViewingCycle(iteration))
			{
				//控制unity3d 进程的退出
				int update_is[2] = { tracker_ptr->get_update(), 2 };
				memcpy(update, update_is, sizeof(int)*2);
				return -1;
			}
		}
	

	return 0;
}


set_body2world_pose实现物体绕自身的旋转

 如果用set_world2body_pose则是物体绕世界坐标原点旋转。

 

void Body::set_body2world_pose(const Transform3fA &body2world_pose) {
  body2world_pose_ = body2world_pose;
  world2body_pose_ = body2world_pose_.inverse();
  geometry2world_pose_ = body2world_pose_ * geometry2body_pose_;
  world2geometry_pose_ = geometry2world_pose_.inverse();
}

void Body::set_world2body_pose(const Transform3fA &world2body_pose) {
  world2body_pose_ = world2body_pose;
  body2world_pose_ = world2body_pose_.inverse();
  geometry2world_pose_ = body2world_pose_ * geometry2body_pose_;
  world2geometry_pose_ = geometry2world_pose_.inverse();
}

void Body::set_geometry2body_pose(const Transform3fA &geometry2body_pose) {
  geometry2body_pose_ = geometry2body_pose;
  geometry2world_pose_ = body2world_pose_ * geometry2body_pose_;
  world2geometry_pose_ = geometry2world_pose_.inverse();
}

const Transform3fA &Body::geometry2body_pose() const {
  return geometry2body_pose_;
}

const Transform3fA &Body::body2world_pose() const { return body2world_pose_; }

const Transform3fA &Body::world2body_pose() const { return world2body_pose_; }

const Transform3fA &Body::geometry2world_pose() const {
  return geometry2world_pose_;
}

const Transform3fA &Body::world2geometry_pose() const {
  return world2geometry_pose_;
}

unity中调用 dll并将值传给c++工程

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
using fts;

public class useDll : MonoBehaviour
{

    [DllImport("run_on_camera_sequence")]
    static extern void main();

    [DllImport("run_on_camera_sequence")]
    //static extern int start_track(int iteration, float[] pos_array, int[] is_update,float[] pos_rt);
    static extern int start_track(int iteration, float[] pos_array, int[] is_update, float x, float y, float z, float w, float pos_x, float pos_y, float pos_z);



    // 为接收dll中计算值开辟空间
    private float[] pos_array = new float[7];
    private int[] is_update = new int[2];

    // 申请变量向dll中传值,改变c++程序的运行逻辑
    // 物体的position
    private float pos_x = 0.095f;
    private float pos_y = 0.1f;
    private float pos_z = -0.4f;

    // 物体的旋转
    private float x = 0.0f;
    private float y = 0.0f;
    private float z = 0.0f;
    private float w = 0.0f;

    Quaternion rotation_ = new Quaternion(0, 0, 0, 1);
    Vector3 trans_ = new Vector3(0, 0, 0);

    public GameObject Target;
    int stop_run = 0;
    bool change_pos = true;

    
    int iteration = 0;


    // Start is called before the first frame update
    void Start()
    {

        main();

        //FooPluginAPI_Auto.mainFun();

    }

    // Update is called once per frame
    void Update()
    {

        if (stop_run != -1)
        {
            //FooPluginAPI_Auto.start_trackFun(iteration, pos_array, is_update);
            stop_run = start_track(iteration, pos_array, is_update, x, y, z, w, pos_x, pos_y, pos_z);
            print(pos_array[4] + "**********" + pos_array[5] + "**********" + pos_array[6] + "**********");
            iteration += 1;

            if (is_update[0] != is_update[1] && (is_update[0] * is_update[1]) == 0)
            {
                rotation_.x = pos_array[0];
                rotation_.y = pos_array[1];
                rotation_.z = pos_array[2];
                rotation_.w = pos_array[3];
                Target.transform.localRotation = rotation_;

                trans_.x = pos_array[4];
                trans_.y = pos_array[5];
                trans_.z = pos_array[6];
                Target.transform.localPosition = trans_;

                print("****localRotation*****" + Target.transform.localRotation + "****localPosition*****" + Target.transform.localPosition);
                print("---change---");
            }

            print("-------[0]------" + is_update[0] + "-------[1]------" + is_update[1]);


            if (is_update[0] == is_update[1])
            {
                x = -Target.transform.localRotation.x;
                y = Target.transform.localRotation.y;
                z = -Target.transform.localRotation.z;
                w = Target.transform.localRotation.w;

                pos_x = Target.transform.localPosition.x;
                pos_y = -Target.transform.localPosition.y;
                pos_z = Target.transform.localPosition.z;

                print("***********pos_z************" + pos_z + "******is_update[0]*****" + is_update[0] + "******is_update[1]*****" + is_update[1]);

                //pos_z = Target.transform.localPosition.z;
            }

        }
        //if ( is_update[1] == 2)
        //{
        //    //is_update[0] = -1;
        //    //is_update[1] = 0;

        //    print("free room");

        //}

    }


}

float[] pos_array, int[] is_update

这两个变量是在unity中使用c++的计算的结果

int iteration,float x, float y, float z, float w, float pos_x, float pos_y, float pos_z

这八个值是从unity中赋值传给c++ dll让其控制程序的逻辑。

应该有更好的方法通过数组一下传过去,但还没搞明白,如果哪位大神整明白了,望分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/781601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单Bank OTA升级:STM32G071 BootLoader (一)

什么是单Bank升级&#xff1a;将Flash划分为以下3个区域。 BootLoader区&#xff1a;程序进行升级的引导程序&#xff0c;根据Upade_Flag来判断跳转Bank区运行程序或是接收升级数据写入Bank&#xff0c;接收完成后擦写Upade_Flag区&#xff0c;进行跳转Bank区运行程序。 Upad…

无线投屏手机(安卓)屏幕到 Linux(ubuntu 22.04)桌面

1.安装 scrcpy 安装 scrcpy会自动安装 adb. 这个版本的adb功能不是最全的&#xff0c;需要删掉&#xff0c;然后从链接 https://dl.google.com/android/repository/platform-tools-latest-darwin.zip 下载&#xff0c;解压安装即可。 2. 在手机上 打开开发者模式和 USB调试…

Git Merge和Rebase

◆ 前言 Git作为我们日常开发代码的版本管理&#xff0c;开发分支的管理方面起着很大作用&#xff0c;我们开发过程中分支通常有生产、预发、测试、开发这几个分支&#xff0c;我们会根据项目进行的某个阶段&#xff0c;将代码提交到某个版本上&#xff0c;正常流程是先开发 —…

【并发专题】阻塞队列BlockingQueue实战及其原理分析

目录 前置知识队列有界队列、无界队列Queue——队列在JAVA里面的接口 阻塞队列介绍BlockingQueue——阻塞队列在JAVA里面的接口阻塞队列的应用场景JUC包下的阻塞队列 课程内容*一、ArrayBlockingQueue基本介绍应用场景使用示例基本原理数据结构核心源码解析双指针与环形数组 *二…

设计模式:创建型模式

抽象工厂 abstract factory 例子 考虑一个多风格的界面应用&#xff0c;要求可以切换不同风格类型的组件&#xff08;窗口&#xff0c;滚动条&#xff0c;按钮等&#xff09; 风格/组件pm风格motif风格滚动条pmScrollBarmotifScrollBar窗口pmWindowMotifWindow WidgetFact…

Vue中TodoList案例_静态

MyHeader.vue <template><div class"todo-header"><input type"text" placeholder"请输入你的任务名称&#xff0c;按回车键确认"></div> </template><script> export default {name: "MyHeader"…

16. python从入门到精通——Python网络爬虫

目录 什么是爬虫 优点 网络爬虫的常用技术 网络请求&#xff1a;有三个常用网络请求模块 Urllib模块&#xff1a;python原生系统中标准库模块 urllib中的子模块 urllib.parse.urlencode() 常用于进行 URL 的 get 请求参数拼接 Urllib3模块&#xff1a;Urllib模块的升级版…

paramiko模块使用(2)

远程查看服务器资源使用情况 单机实现 import paramiko# 定义远程服务器的连接信息 hostname 192.168.2.198 username root password 123456# 创建SSH客户端对象 client paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy())try:# 连接到…

力扣刷题SQL-197. 上升的温度---分步解题

表&#xff1a; Weather ------------------------ | Column Name | Type | ------------------------ | id | int | | recordDate | date | | temperature | int | ------------------------ id 是这个表的主键 该表包含特定日期的温度信息编…

qemu搭建arm环境以及文件共享

几乎完全参照该文章 使用QEMU搭建ARM64实验环境 - 简书 ubuntu 14.04&#xff0c;linux3.16&#xff0c; busybox-1.31.0 arm-linux-gnueabi-gcc -v linux3.16以及busybox下载安装可参考链接 Ubuntu14.04安装qemu&#xff0c;运行linux-3.16gdb调试_qemu 安装 ubuntu 14_这个我…

项目开启启动命令整合

启动RabbitMQ管理插件 1.启动 RabbitMQ 管理插件。 rabbitmq-plugins enable rabbitmq_management rabbitmq-server # 直接启动&#xff0c;如果关闭窗⼝或需要在该窗⼝使⽤其他命令时应⽤就会停⽌ rabbitmq-server -detached # 后台启动 rabbitmq-server start # 启⽤服务 rab…

【亲测可用】安装Qt提示“无法下载存档 http://download.qt.io/online/qtsdkrepository...“

下载Qt安装程序exe之后&#xff0c;一般直接双击运行然后&#xff0c;注册登录后&#xff0c;到了第三步【安装程序】时&#xff0c;进行远程检索文件总会卡在这里&#xff0c;无法进行到下一步。报错如下&#xff1a; 解决办法&#xff1a; 关闭安装程序&#xff0c;然后&…

一百三十二、ClickHouse——ClickHouse建表时默认字段非空导致数据问题

一、ClickHouse建表问题 由于ClickHouse建表时默认字段非空 &#xff08;一&#xff09;建表语句 &#xff08;二&#xff09;查看字段属性 ClickHouse建表时一般情况下直接默认字段非空 &#xff08;三&#xff09;导致问题 所以这就导致一般情况下&#xff0c;一些字段的…

iphone新机官网验机流程

苹果官网验机流程 进入苹果官网&#xff0c;找到技术支持&#xff0c;进入“查看保障服务和支持期限“页面&#xff0c;输入要查询的机器的序列号&#xff0c;就可以查询了。 苹果官网验机入口&#xff1a;https://checkcoverage.apple.com/ 输入iphone序列号进行验机&#xff…

小程序体验版上线注意事项

1.接口域名必须是https&#xff0c;有ssh证书。不能用ip地址。 2.需要在微信公众平台进行配置 微信公众平台->开发-> 开发管理->开发设置 对服务器域名和业务域名进行配置对业务域名进行配置时&#xff0c;需要下载校验文件&#xff0c;放在域名根目录下

力扣刷题27.移除元素(Accept03)

力扣刷题 代码随想录数组 3.移除元素 力扣27. 移除元素 方法一&#xff1a;暴力解决法 1. 思路 两层嵌套循环遍历数组&#xff0c;内层循环主要是当第一层循环遍历到的元素等于要移除的元素的值的时候&#xff0c;其后的元素依次向前挪动一个位置&#xff08;覆盖要删除的…

计科web常见错误排错【HTTP状态404、导航栏无法点开、字符乱码及前后端数据传输呈现、jsp填写的数据传到数据库显示null、HTTP状态500】

web排错记录 在使用javaweb的过程中会出现的一些错误请在下方目录查找。 目录 错误1&#xff1a;HTTP状态404——未找到 错误2&#xff1a;导航栏下拉菜单无法点开的问题 错误3&#xff1a;字符乱码问题 错误4&#xff1a;jsp网页全部都是&#xff1f;&#xff1f;&#x…

科技云报道:边缘云赛道开启,谁能成为首个“出线”厂商?

科技云报道原创。 每一轮底层技术变革&#xff0c;都会带来全新的商业机遇。随着万物智联时代到来&#xff0c;大量数据产生的源头由传统的中心化向分散数据源变革&#xff0c;越来越多云边协同场景的出现&#xff0c;使得边缘云成为计算领域数据处理的新范式之一。 自2020年…

CHI协议保序之Compack保序

一致性系统中&#xff0c;使用三种保序方式&#xff1b; Completion ack response ⭕Completion acknowledgment&#xff1a; □ 该域段主要是用来&#xff0c; □ 决定 RN 发送的 trans&#xff0c;与其他 RN 发送的命令产生的 SNP 之间的顺序&#xff1b; …

[VUE]Element_UI 实现TreeSelect 树形选择器

文章目录 前言1、安装2、引用3、使用 前言 最近在做一个人员管理系统&#xff0c;在增改用户信息时&#xff0c;可能会设置用户所在的部门&#xff0c;因为部门是多级的&#xff0c;于是想到用Element_UI的TreeSelect组件实现 效果&#xff1a; 1、安装 npm install --save…