找回密码
 立即注册
查看: 511|回复: 0

Unreal之Houdini Api 学习

[复制链接]
发表于 2021-3-11 10:07 | 显示全部楼层 |阅读模式
20210226
目前游戏领域中,程序化内容生产(Procedural  Content Generation, PCG)的比重越来越重,其中Houdini工具的运用占据了主要比例。目前网上很多资料都是偏向于美术侧,本文着重讲一些程序侧方向,主要是平时学习的记录。
Houdini Api地址:https://www.sidefx.com/docs/hengine17.5/index.html
一. 版本问题

Houdini 对于版本要求很高,在项目中一般我们都是要求每个人安装的版本都必须一致。在学习过程中,需要区分下Houdini 软件版本和api版本,一面误导。
其中Houdini软件版本指的是我们实际安装软件的版本,一般在软件icon上就能看到。例如如下所示:
Houdini Api 版本则只能通过代码中查看,查看位置:HAPI_Version.h中:
  1. // The two components of the Houdini Engine (marketed) version.
  2. #define HAPI_VERSION_HOUDINI_ENGINE_MAJOR 3
  3. #define HAPI_VERSION_HOUDINI_ENGINE_MINOR 2
复制代码
这里指定了我当前使用的Houdini Api 版本是3.2。同时,在这一个文件中也记录了对应的软件版本:
  1. // The three components of the Houdini version that HAPI is
  2. // expecting to compile against.
  3. #define HAPI_VERSION_HOUDINI_MAJOR 17
  4. #define HAPI_VERSION_HOUDINI_MINOR 5
  5. #define HAPI_VERSION_HOUDINI_BUILD 391
  6. #define HAPI_VERSION_HOUDINI_PATCH 0
复制代码
另一方面,Houdini api 库提供函数HAPI_GetEnvInt()用来获取版本内容,通过给定HAPI_EnvIntType字段可获取到特定版本信息,类似代码如下:
  1. int32 RunningMajor = 0;
  2. int32 RunningMinor = 0;
  3. int32 RunningBuild = 0;
  4. int32 RunningPatch = 0;
  5. if ( FHoudiniApi::IsHAPIInitialized() )
  6. {
  7.      const HAPI_Session * Session = FHoudiniEngine::Get().GetSession();
  8.      // Retrieve version numbers for running Houdini.
  9.      FHoudiniApi::GetEnvInt( HAPI_ENVINT_VERSION_HOUDINI_MAJOR, &RunningMajor );
  10.      FHoudiniApi::GetEnvInt( HAPI_ENVINT_VERSION_HOUDINI_MINOR, &RunningMinor );
  11.      FHoudiniApi::GetEnvInt( HAPI_ENVINT_VERSION_HOUDINI_BUILD, &RunningBuild );
  12.      FHoudiniApi::GetEnvInt( HAPI_ENVINT_VERSION_HOUDINI_PATCH, &RunningPatch );
  13. }
复制代码
Ps:由于本地是Unreal版本的Houdini 库,与原生Houdini库存在一些差异,但并不影响理解,因此就手动改代码了。
二. 文件介绍

Houdini 安装之后,会提供Houdini Api库文件(同时会提供unity、unreal、maya等平台库文件)。路径参考如下:
  1. C:\Program Files\Side Effects Software\Houdini 17.5.391\toolkit\include\HAPI
复制代码
库文件包含:
  1. HAPI.h // 声明所有API格式
  2. HAPI_Common.h // 定义用到结构和枚举类
  3. HAPI_Version.h // 版本信息
  4. HAPI_Helpers.h // 声明一些用来初始化结构的函数
  5. HAPI_API.h // 链接库 和其他一些定义
复制代码
三. 对字符串的处理

通常情况下,如果我们要从houdini获取一个字符串,比方获取一个HAD参数面板的一个属性:字段为file的路径。Houdini并不是直接返回一个string,而是通过HAPI_StringHandle形式。通过HAPI_StringHandle,我们会获取到该string的id,然后根据这个id获取到具体的string。
HAPI_StringHandle的定义如下:
  1. // HAPI_Common.h
  2. /// Use this with HAPI_GetString() to get the value.
  3. /// See @ref HAPI_Fundamentals_Strings.
  4. typedef int HAPI_StringHandle;
复制代码
下面给出2个具体通过HAPI_StringHandle过得到string的方案。
方案一:HAPI_GetStringBufLength() + HAPI_GetString()
通过HAPI_GetStringBufLength获取到字符串长度(buffer),然后HAPI_GetString()获取。类似代码如下:
  1. int buffer_length;
  2. HAPI_GetStatusStringBufLength(
  3.      nullptr, id, HAPI_STATUSVERBOSITY_ERRORS, &buffer_length );
  4. char * buf = new char[ buffer_length ];
  5. HAPI_GetStatusString( nullptr, id, buf );
  6. std::string result( buf ); // result 即为字符串
  7. delete[] buf;
复制代码
Ps:这点代码是由官方提供,暂时未经过测试(想来应该也是能用的),HAPI_GetStatusStringBufLength 第三个参数还需要测试一下。
方案二:FHoudiniEngineString函数
FHoudiniEngineString是Houdini Api中Unreal引擎侧的一个类,具体路径位置在HoudiniEngineString.h文件中,通过提供的toString方法,可以获得到给定string id的string值。具体代码类似如下:
  1. // 获取csv路径
  2. HAPI_StringHandle MatNamesValueHandle;
  3. HAPI_Result result;
  4. FString csvPath = "";
  5. result = FHoudiniApi::GetParmStringValue(
  6.      FHoudiniEngine::Get().GetSession(), NodeId, TCHAR_TO_UTF8(*(FString("file"))), 0, 0, &MatNamesValueHandle);
  7. FHoudiniEngineString(MatNamesValueHandle).ToFString(csvPath);
复制代码
GetParmStringValue函数根据给定的参数,获取到属性面板对应参数。
四. 获取Houdini 错误信息

基本上所有Houdini函数的返回结果都是HAPI_Result,通过HAPI_Result可以得到函数具体结果,其中除了HAPI_RESULT_SUCCESS意外,其他均是错误信息。因此有些时候我们很有必要得到错误信息内容。通过以下函数,我们可以获取到具体错误信息:
  1. static std::string get_last_error()
  2. {
  3.      int buffer_length;
  4.      HAPI_GetStatusStringBufLength(
  5.          nullptr, HAPI_STATUS_CALL_RESULT, HAPI_STATUSVERBOSITY_ERRORS, &buffer_length );
  6.      char * buf = new char[ buffer_length ];
  7.      HAPI_GetStatusString( nullptr, HAPI_STATUS_CALL_RESULT, buf );
  8.      std::string result( buf );
  9.      delete[] buf;
  10.      return result;
  11. }
复制代码
五. 总结

暂时第一部分Houdini学习就到这里为止,都是一些比较基本的内容,重在抛砖引玉。下个内容,给出一些关于创建节点和Houdini交互的相关内容吧。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-20 18:00 , Processed in 0.089128 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表