aboutsummaryrefslogtreecommitdiff
path: root/vrayPlug/plugin
diff options
context:
space:
mode:
authorBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
committerBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
commitbd0027e737c6512397f841c22786274ed74b927f (patch)
treef7ffbdb8f3741bb7f24635616cc189cba5cb865c /vrayPlug/plugin
downloadarchived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz
archived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'vrayPlug/plugin')
-rw-r--r--vrayPlug/plugin/LinuxSh_x64_vray36.mak114
-rw-r--r--vrayPlug/plugin/LinuxSh_x64_vray40.mak119
-rw-r--r--vrayPlug/plugin/Linux_x64_vray36.mak196
-rw-r--r--vrayPlug/plugin/Linux_x64_vray40.mak195
-rw-r--r--vrayPlug/plugin/hairAPI.h835
-rw-r--r--vrayPlug/plugin/hairAPIimp.cpp1464
-rw-r--r--vrayPlug/plugin/hairAPIimp.h333
-rw-r--r--vrayPlug/plugin/hairAPIvray.h86
-rw-r--r--vrayPlug/plugin/hairAPIvrayutil.h90
-rw-r--r--vrayPlug/plugin/osxMavericks_x64_vray36.mak173
-rw-r--r--vrayPlug/plugin/osxMavericks_x64_vray40.mak173
-rw-r--r--vrayPlug/plugin/pluginMain.cpp259
-rw-r--r--vrayPlug/plugin/shaderMain.cpp51
-rw-r--r--vrayPlug/plugin/shaveSDKCALLBACKS.c97
-rw-r--r--vrayPlug/plugin/shaveVray-vs11.sln35
-rw-r--r--vrayPlug/plugin/shaveVray-vs11.vcxproj407
-rw-r--r--vrayPlug/plugin/shaveVray-vs15.sln40
-rw-r--r--vrayPlug/plugin/shaveVray-vs15.vcxproj453
-rw-r--r--vrayPlug/plugin/shaveVrayBaseBSDF.cpp325
-rw-r--r--vrayPlug/plugin/shaveVrayBaseBSDF.h137
-rw-r--r--vrayPlug/plugin/shaveVrayBaseBSDFPool.cpp25
-rw-r--r--vrayPlug/plugin/shaveVrayBaseBSDFPool.h30
-rw-r--r--vrayPlug/plugin/shaveVrayDesc.cpp26
-rw-r--r--vrayPlug/plugin/shaveVrayDesc.h20
-rw-r--r--vrayPlug/plugin/shaveVrayInstance.cpp233
-rw-r--r--vrayPlug/plugin/shaveVrayInstance.h147
-rw-r--r--vrayPlug/plugin/shaveVrayInstanceBase.cpp153
-rw-r--r--vrayPlug/plugin/shaveVrayInstanceBase.h105
-rw-r--r--vrayPlug/plugin/shaveVrayInstanceI.cpp162
-rw-r--r--vrayPlug/plugin/shaveVrayInstanceI.h93
-rw-r--r--vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp353
-rw-r--r--vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.h108
-rw-r--r--vrayPlug/plugin/shaveVrayMovingVoxelPrim.cpp948
-rw-r--r--vrayPlug/plugin/shaveVrayMovingVoxelPrim.h232
-rw-r--r--vrayPlug/plugin/shaveVrayPlugin.cpp306
-rw-r--r--vrayPlug/plugin/shaveVrayPlugin.h233
-rw-r--r--vrayPlug/plugin/shaveVraySh-vs11.sln44
-rw-r--r--vrayPlug/plugin/shaveVraySh-vs11.vcxproj365
-rw-r--r--vrayPlug/plugin/shaveVraySh-vs15.sln30
-rw-r--r--vrayPlug/plugin/shaveVraySh-vs15.vcxproj366
-rw-r--r--vrayPlug/plugin/shaveVraySh.def9
-rw-r--r--vrayPlug/plugin/shaveVrayShadeData.cpp268
-rw-r--r--vrayPlug/plugin/shaveVrayShadeData.h124
-rw-r--r--vrayPlug/plugin/shaveVrayShadeInstance.h64
-rw-r--r--vrayPlug/plugin/shaveVrayShadeable.cpp258
-rw-r--r--vrayPlug/plugin/shaveVrayShadeable.h109
-rw-r--r--vrayPlug/plugin/shaveVraySharedFunctions.cpp483
-rw-r--r--vrayPlug/plugin/shaveVraySharedFunctions.h61
-rw-r--r--vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.cpp352
-rw-r--r--vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.h100
-rw-r--r--vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp790
-rw-r--r--vrayPlug/plugin/shaveVrayStaticVoxelPrim.h203
-rw-r--r--vrayPlug/plugin/shaveVrayTriShadeData.cpp152
-rw-r--r--vrayPlug/plugin/shaveVrayTriShadeData.h72
-rw-r--r--vrayPlug/plugin/shaveVrayTriShadeable.cpp151
-rw-r--r--vrayPlug/plugin/shaveVrayTriShadeable.h93
-rw-r--r--vrayPlug/plugin/shaveVrayTriVoxelPrim.cpp42
-rw-r--r--vrayPlug/plugin/shaveVrayTriVoxelPrim.h60
-rw-r--r--vrayPlug/plugin/shaveVrayVoxelPrim.cpp279
-rw-r--r--vrayPlug/plugin/shaveVrayVoxelPrim.h167
-rw-r--r--vrayPlug/plugin/shaveVrayVoxelPrimBase.h75
-rw-r--r--vrayPlug/plugin/vray3_compat.h132
62 files changed, 13605 insertions, 0 deletions
diff --git a/vrayPlug/plugin/LinuxSh_x64_vray36.mak b/vrayPlug/plugin/LinuxSh_x64_vray36.mak
new file mode 100644
index 0000000..f6764da
--- /dev/null
+++ b/vrayPlug/plugin/LinuxSh_x64_vray36.mak
@@ -0,0 +1,114 @@
+####################################################################
+#
+# Maya Location & Version
+#
+####################################################################
+ifndef MAYA_LOCATION
+$(error "MAYA_LOCATION is not defined")
+endif
+
+ifeq ($(wildcard $(MAYA_LOCATION)),)
+$(error "MAYA_LOCATION contains '$(MAYA_LOCATION)', which does not exist.")
+endif
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+versionInfo := $(shell ../../utils/getMayaAPIVersion.sh)
+mayaAPI := $(word 1,$(versionInfo))
+mayaVersion := $(word 2,$(versionInfo))
+mayaMajorVersion := $(word 3, $(versionInfo))
+mayaMinorVersion := $(word 4, $(versionInfo))
+
+ifeq ($(findstring -x64,$(MAYA_LOCATION)),-x64)
+ mayaVersion := $(mayaVersion)-x64
+endif
+
+
+####################################################################
+#
+# Compiler & Linker
+#
+####################################################################
+
+C++ = $(shell ../../utils/getg++vray.sh $(mayaVersion) 36)
+CC = $(subst ++,cc,$(C++))
+
+ifeq ($(C++),)
+ $(error "Maya version $(mayaVersion) not supported.")
+endif
+
+
+#
+# vray include/lib path
+#
+# you should replace it with own paths
+
+VRAY_LDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/linux
+VRAY_IDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include
+
+#
+# output and temp dirs
+#
+OUTDIR = ../bin/linux_x64
+TMPDIR = ./build/release/linux_x64/gcc-4.4/vray36
+
+
+OBJS = \
+$(TMPDIR)/shaderMain.obj \
+$(TMPDIR)/shaveVrayBaseBSDF.obj \
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj \
+$(VRAY_LDIR)/libvutils_s.a \
+$(VRAY_LDIR)/libplugman_s.a \
+$(VRAY_LDIR)/librayserver_s.a
+
+
+
+GCCFLAGS = -v -Wall -lpthread -lrt -lc -lz -fPIC
+GCCFLAGS_OBJ = -O2 -ffunction-sections -fdata-sections -finline-functions -funswitch-loops -fgcse-after-reload -ffast-math -fPIC -DHAVE_EXR -DBits64_ -D_REENTRANT -fexceptions -DVRAY30
+GCCLDFLAGS = -Bsymbolic
+
+#
+# vray libs
+#
+LIBS = -ldl -lvray
+
+
+LIBDIRS = -L. -L$(VRAY_LDIR)
+INCDIRS = -I. -I$(VRAY_IDIR)
+
+all: ../bin/linux_x64/ShaveSh36.so
+
+../bin/linux_x64/ShaveSh36.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(GCCLDFLAGS) $(LIBDIRS) -shared -Wl,--export-dynamic -o "$(OUTDIR)/ShaveSh36.so" "-Wl,-(" $(OBJS) $(LIBS) "-Wl,-)"
+
+
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+
+
+$(TMPDIR)/shaderMain.obj: shaderMain.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaderMain.obj" "shaderMain.cpp"
+
+
+$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj: shaveVrayBaseBSDFPool.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDFPool.obj" "shaveVrayBaseBSDFPool.cpp"
+
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/ShaveSh36.so
+
diff --git a/vrayPlug/plugin/LinuxSh_x64_vray40.mak b/vrayPlug/plugin/LinuxSh_x64_vray40.mak
new file mode 100644
index 0000000..2a982db
--- /dev/null
+++ b/vrayPlug/plugin/LinuxSh_x64_vray40.mak
@@ -0,0 +1,119 @@
+####################################################################
+#
+# Maya Location & Version
+#
+####################################################################
+ifndef MAYA_LOCATION
+$(error "MAYA_LOCATION is not defined")
+endif
+
+ifeq ($(wildcard $(MAYA_LOCATION)),)
+$(error "MAYA_LOCATION contains '$(MAYA_LOCATION)', which does not exist.")
+endif
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+versionInfo := $(shell ../../utils/getMayaAPIVersion.sh)
+mayaAPI := $(word 1,$(versionInfo))
+mayaVersion := $(word 2,$(versionInfo))
+mayaMajorVersion := $(word 3, $(versionInfo))
+mayaMinorVersion := $(word 4, $(versionInfo))
+
+ifeq ($(findstring -x64,$(MAYA_LOCATION)),-x64)
+ mayaVersion := $(mayaVersion)-x64
+endif
+
+
+####################################################################
+#
+# Compiler & Linker
+#
+####################################################################
+
+C++ = $(shell ../../utils/getg++vray.sh $(mayaVersion) 40)
+CC = $(subst ++,cc,$(C++))
+
+ifeq ($(C++),)
+ $(error "Maya version $(mayaVersion) not supported.")
+endif
+
+# sanity check
+ifeq (,$(findstring 4.8,$(shell $(C++) --version)))
+ $(error "V-Ray 4.0 must be built with gcc-4.8!")
+endif
+
+
+#
+# vray include/lib path
+#
+# you should replace it with own paths
+
+VRAY_LDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/linux
+VRAY_IDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include
+
+#
+# output and temp dirs
+#
+OUTDIR = ../bin/linux_x64
+TMPDIR = ./build/release/linux_x64/clang-gcc-4.8/vray40
+
+
+OBJS = \
+$(TMPDIR)/shaderMain.obj \
+$(TMPDIR)/shaveVrayBaseBSDF.obj \
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj \
+$(VRAY_LDIR)/libvutils_s.a \
+$(VRAY_LDIR)/libplugman_s.a \
+$(VRAY_LDIR)/librayserver_s.a
+
+
+
+GCCFLAGS = -v -Wall -lpthread -lrt -lc -lz -fPIC
+GCCFLAGS_OBJ = -std=c++11 -O2 -ffunction-sections -fdata-sections -finline-functions -funswitch-loops -fgcse-after-reload -ffast-math -fPIC -DHAVE_EXR -DBits64_ -D_REENTRANT -fexceptions -DVRAY40
+GCCLDFLAGS = -Bsymbolic
+
+#
+# vray libs
+#
+LIBS = -ldl -lvray
+
+
+LIBDIRS = -L. -L$(VRAY_LDIR)
+INCDIRS = -I. -I$(VRAY_IDIR)
+
+all: ../bin/linux_x64/ShaveSh40.so
+
+../bin/linux_x64/ShaveSh40.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(GCCLDFLAGS) $(LIBDIRS) -shared -Wl,--export-dynamic -o "$(OUTDIR)/ShaveSh40.so" "-Wl,-(" $(OBJS) $(LIBS) "-Wl,-)"
+
+
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+
+
+$(TMPDIR)/shaderMain.obj: shaderMain.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaderMain.obj" "shaderMain.cpp"
+
+
+$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj: shaveVrayBaseBSDFPool.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDFPool.obj" "shaveVrayBaseBSDFPool.cpp"
+
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/ShaveSh40.so
+
diff --git a/vrayPlug/plugin/Linux_x64_vray36.mak b/vrayPlug/plugin/Linux_x64_vray36.mak
new file mode 100644
index 0000000..9838282
--- /dev/null
+++ b/vrayPlug/plugin/Linux_x64_vray36.mak
@@ -0,0 +1,196 @@
+####################################################################
+#
+# Maya Location & Version
+#
+####################################################################
+ifndef MAYA_LOCATION
+$(error "MAYA_LOCATION is not defined.")
+endif
+
+ifeq ($(wildcard $(MAYA_LOCATION)),)
+$(error "MAYA_LOCATION contains '$(MAYA_LOCATION)', which does not exist.")
+endif
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+versionInfo := $(shell ../../utils/getMayaAPIVersion.sh)
+mayaAPI := $(word 1,$(versionInfo))
+mayaVersion := $(word 2,$(versionInfo))
+mayaMajorVersion := $(word 3, $(versionInfo))
+mayaMinorVersion := $(word 4, $(versionInfo))
+
+ifeq ($(findstring -x64,$(MAYA_LOCATION)),-x64)
+ mayaVersion := $(mayaVersion)-x64
+endif
+
+
+####################################################################
+#
+# Compiler & Linker
+#
+####################################################################
+
+C++ = $(shell ../../utils/getg++vray.sh $(mayaVersion) 36)
+CC = $(subst ++,cc,$(C++))
+
+ifeq ($(C++),)
+ $(error "Maya version $(mayaVersion) not supported.")
+endif
+
+
+OUTDIR = ../bin/linux_x64
+TMPDIR = ./build/release/linux_x64/gcc-4.4/vray36
+
+VRAY_LDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/linux
+VRAY_IDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include
+
+OBJS = \
+$(TMPDIR)/shaveSDKCALLBACKS.obj \
+$(TMPDIR)/hairAPIimp.obj \
+$(TMPDIR)/pluginMain.obj \
+$(TMPDIR)/shaveVrayDesc.obj \
+$(TMPDIR)/shaveVrayInstance.obj \
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj \
+$(TMPDIR)/shaveVrayPlugin.obj \
+$(TMPDIR)/shaveVrayShadeable.obj \
+$(TMPDIR)/shaveVrayShadeData.obj \
+$(TMPDIR)/shaveVraySharedFunctions.obj \
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj \
+$(TMPDIR)/shaveVrayVoxelPrim.obj \
+$(TMPDIR)/shaveVrayInstanceBase.obj \
+$(TMPDIR)/shaveVrayInstanceI.obj \
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayTriShadeable.obj \
+$(TMPDIR)/shaveVrayTriShadeData.obj
+
+
+
+GCCFLAGS = -g -Wall -pthread -lrt -lc -lz -fPIC
+GCCFLAGS_OBJ = -O0 -g -ffunction-sections -fdata-sections -finline-functions -funswitch-loops -fgcse-after-reload -ffast-math -fPIC -DHAVE_EXR -DBits64_ -D_REENTRANT -DLINUX -fexceptions -DVRAY30 -DVRAY_DUAL -DVRAY_EXPORTS
+GCCLDFLAGS = -Bsymbolic
+
+# intrisics.h thinks that _mm_cvtss_f32() and some other funcs are
+# missing from the "gcc 4.1" headers and thus provides its own. However, those
+# funcs *are* present in our gcc 4.1.2 headers, so we want to avoid having
+# vray redefine them.
+#
+GCCFLAGS_OBJ += -D_GCC41_MM_CVTSS_F32_FIX__MATH_H__
+
+#
+# shave related libs
+#
+SHAVELIB = "../../libexe/shavelibAW2-x64.a"
+
+#
+# std libs
+#
+LIBS = -lvutils_s -lplugman_s -lrayserver_s -lvray -ldl $(SHAVELIB)
+LIBDIRS = -L. -L$(VRAY_LDIR) -L"../libs/shave/linux64"
+INCDIRS = -I. -I$(VRAY_IDIR) -I"../../libexe/sample/include"
+
+all: ../bin/linux_x64/libvray_Shave36.so
+
+../bin/linux_x64/libvray_Shave36.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(GCCLDFLAGS) $(LIBDIRS) -shared -z defs -Wl,--export-dynamic -o "$(OUTDIR)/libvray_Shave36.so" "-Wl,-(" $(OBJS) $(LIBS) "-Wl,-)"
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+$(TMPDIR)/shaveSDKCALLBACKS.obj: shaveSDKCALLBACKS.c
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveSDKCALLBACKS.obj" "shaveSDKCALLBACKS.c"
+
+
+$(TMPDIR)/hairAPIimp.obj: hairAPIimp.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/hairAPIimp.obj" "hairAPIimp.cpp"
+
+
+$(TMPDIR)/pluginMain.obj: pluginMain.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/pluginMain.obj" "pluginMain.cpp"
+
+#goes to LinuxSh_x64.mak
+#$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+# $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+
+$(TMPDIR)/shaveVrayDesc.obj: shaveVrayDesc.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayDesc.obj" "shaveVrayDesc.cpp"
+
+
+$(TMPDIR)/shaveVrayInstance.obj: shaveVrayInstance.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstance.obj" "shaveVrayInstance.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj: shaveVrayMovingVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayMovingVoxelPrim.obj" "shaveVrayMovingVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayPlugin.obj: shaveVrayPlugin.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayPlugin.obj" "shaveVrayPlugin.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeable.obj: shaveVrayShadeable.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayShadeable.obj" "shaveVrayShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeData.obj: shaveVrayShadeData.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayShadeData.obj" "shaveVrayShadeData.cpp"
+
+
+$(TMPDIR)/shaveVraySharedFunctions.obj: shaveVraySharedFunctions.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVraySharedFunctions.obj" "shaveVraySharedFunctions.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj: shaveVrayStaticVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayStaticVoxelPrim.obj" "shaveVrayStaticVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayVoxelPrim.obj: shaveVrayVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayVoxelPrim.obj" "shaveVrayVoxelPrim.cpp"
+
+
+#instanced hair
+
+$(TMPDIR)/shaveVrayInstanceBase.obj: shaveVrayInstanceBase.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstanceBase.obj" "shaveVrayInstanceBase.cpp"
+
+
+$(TMPDIR)/shaveVrayInstanceI.obj: shaveVrayInstanceI.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstanceI.obj" "shaveVrayInstanceI.cpp"
+
+
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj: shaveVrayTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriVoxelPrim.obj" "shaveVrayTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj: shaveVrayMovingTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj" "shaveVrayMovingTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj: shaveVrayStaticTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj" "shaveVrayStaticTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeable.obj: shaveVrayTriShadeable.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriShadeable.obj" "shaveVrayTriShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeData.obj: shaveVrayTriShadeData.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriShadeData.obj" "shaveVrayTriShadeData.cpp"
+
+
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/libvray_Shave36.so
+
diff --git a/vrayPlug/plugin/Linux_x64_vray40.mak b/vrayPlug/plugin/Linux_x64_vray40.mak
new file mode 100644
index 0000000..20810f4
--- /dev/null
+++ b/vrayPlug/plugin/Linux_x64_vray40.mak
@@ -0,0 +1,195 @@
+####################################################################
+#
+# Maya Location & Version
+#
+####################################################################
+ifndef MAYA_LOCATION
+$(error "MAYA_LOCATION is not defined")
+endif
+
+ifeq ($(wildcard $(MAYA_LOCATION)),)
+$(error "MAYA_LOCATION contains '$(MAYA_LOCATION)', which does not exist.")
+endif
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+versionInfo := $(shell ../../utils/getMayaAPIVersion.sh)
+mayaAPI := $(word 1,$(versionInfo))
+mayaVersion := $(word 2,$(versionInfo))
+mayaMajorVersion := $(word 3, $(versionInfo))
+mayaMinorVersion := $(word 4, $(versionInfo))
+
+ifeq ($(findstring -x64,$(MAYA_LOCATION)),-x64)
+ mayaVersion := $(mayaVersion)-x64
+endif
+
+
+####################################################################
+#
+# Compiler & Linker
+#
+####################################################################
+
+C++ = $(shell ../../utils/getg++vray.sh $(mayaVersion) 40)
+CC = $(subst ++,cc,$(C++))
+
+ifeq ($(C++),)
+ $(error "Maya version $(mayaVersion) not supported.")
+endif
+
+OUTDIR = ../bin/linux_x64
+TMPDIR = ./build/release/linux_x64/clang-gcc-4.8/vray40
+
+VRAY_LDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/linux
+VRAY_IDIR = $(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include
+
+OBJS = \
+$(TMPDIR)/shaveSDKCALLBACKS.obj \
+$(TMPDIR)/hairAPIimp.obj \
+$(TMPDIR)/pluginMain.obj \
+$(TMPDIR)/shaveVrayDesc.obj \
+$(TMPDIR)/shaveVrayInstance.obj \
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj \
+$(TMPDIR)/shaveVrayPlugin.obj \
+$(TMPDIR)/shaveVrayShadeable.obj \
+$(TMPDIR)/shaveVrayShadeData.obj \
+$(TMPDIR)/shaveVraySharedFunctions.obj \
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj \
+$(TMPDIR)/shaveVrayVoxelPrim.obj \
+$(TMPDIR)/shaveVrayInstanceBase.obj \
+$(TMPDIR)/shaveVrayInstanceI.obj \
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayTriShadeable.obj \
+$(TMPDIR)/shaveVrayTriShadeData.obj
+
+
+
+GCCFLAGS = -g -Wall -pthread -lrt -lc -lz -fPIC
+GCCFLAGS_OBJ = -std=c++11 -ffunction-sections -fdata-sections -finline-functions -funswitch-loops -fgcse-after-reload -ffast-math -fPIC -DHAVE_EXR -DBits64_ -D_REENTRANT -DLINUX -fexceptions -DVRAY40 -DVRAY_DUAL -DVRAY_EXPORTS
+GCCLDFLAGS = -Bsymbolic
+
+# intrisics.h thinks that _mm_cvtss_f32() and some other funcs are
+# missing from the "gcc 4.1" headers and thus provides its own. However, those
+# funcs *are* present in our gcc 4.1.2 headers, so we want to avoid having
+# vray redefine them.
+#
+GCCFLAGS_OBJ += -D_GCC41_MM_CVTSS_F32_FIX__MATH_H__
+
+#
+# shave related libs
+#
+SHAVELIB = "../../libexe/shavelibAW2-x64.a"
+
+#
+# std libs
+#
+LIBS = -lvutils_s -lplugman_s -lrayserver_s -lvray -ldl $(SHAVELIB)
+LIBDIRS = -L. -L$(VRAY_LDIR) -L"../libs/shave/linux64"
+INCDIRS = -I. -I$(VRAY_IDIR) -I"../../libexe/sample/include"
+
+all: ../bin/linux_x64/libvray_Shave40.so
+
+../bin/linux_x64/libvray_Shave40.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(GCCLDFLAGS) $(LIBDIRS) -shared -z defs -Wl,--export-dynamic -o "$(OUTDIR)/libvray_Shave40.so" "-Wl,-(" $(OBJS) $(LIBS) "-Wl,-)"
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+$(TMPDIR)/shaveSDKCALLBACKS.obj: shaveSDKCALLBACKS.c
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveSDKCALLBACKS.obj" "shaveSDKCALLBACKS.c"
+
+
+$(TMPDIR)/hairAPIimp.obj: hairAPIimp.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/hairAPIimp.obj" "hairAPIimp.cpp"
+
+
+$(TMPDIR)/pluginMain.obj: pluginMain.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/pluginMain.obj" "pluginMain.cpp"
+
+#goes to LinuxSh_x64.mak
+#$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+# $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+
+$(TMPDIR)/shaveVrayDesc.obj: shaveVrayDesc.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayDesc.obj" "shaveVrayDesc.cpp"
+
+
+$(TMPDIR)/shaveVrayInstance.obj: shaveVrayInstance.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstance.obj" "shaveVrayInstance.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj: shaveVrayMovingVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayMovingVoxelPrim.obj" "shaveVrayMovingVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayPlugin.obj: shaveVrayPlugin.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayPlugin.obj" "shaveVrayPlugin.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeable.obj: shaveVrayShadeable.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayShadeable.obj" "shaveVrayShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeData.obj: shaveVrayShadeData.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayShadeData.obj" "shaveVrayShadeData.cpp"
+
+
+$(TMPDIR)/shaveVraySharedFunctions.obj: shaveVraySharedFunctions.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVraySharedFunctions.obj" "shaveVraySharedFunctions.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj: shaveVrayStaticVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayStaticVoxelPrim.obj" "shaveVrayStaticVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayVoxelPrim.obj: shaveVrayVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayVoxelPrim.obj" "shaveVrayVoxelPrim.cpp"
+
+
+#instanced hair
+
+$(TMPDIR)/shaveVrayInstanceBase.obj: shaveVrayInstanceBase.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstanceBase.obj" "shaveVrayInstanceBase.cpp"
+
+
+$(TMPDIR)/shaveVrayInstanceI.obj: shaveVrayInstanceI.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayInstanceI.obj" "shaveVrayInstanceI.cpp"
+
+
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj: shaveVrayTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriVoxelPrim.obj" "shaveVrayTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj: shaveVrayMovingTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj" "shaveVrayMovingTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj: shaveVrayStaticTriVoxelPrim.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj" "shaveVrayStaticTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeable.obj: shaveVrayTriShadeable.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriShadeable.obj" "shaveVrayTriShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeData.obj: shaveVrayTriShadeData.cpp
+ $(C++) $(GCCFLAGS_OBJ) $(INCDIRS) -D "NDEBUG" -c -o "$(TMPDIR)/shaveVrayTriShadeData.obj" "shaveVrayTriShadeData.cpp"
+
+
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/libvray_Shave40.so
+
diff --git a/vrayPlug/plugin/hairAPI.h b/vrayPlug/plugin/hairAPI.h
new file mode 100644
index 0000000..816c236
--- /dev/null
+++ b/vrayPlug/plugin/hairAPI.h
@@ -0,0 +1,835 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: hairAPI.h
+
+ DESCRIPTION: C++ Intefraces for SHAVE2 functions
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-08-2008
+
+ *>
+ **********************************************************************/
+
+#ifndef _SHAVE2_API_H_
+#define _SHAVE2_API_H_
+
+
+extern "C"
+{
+#include "shaveSDKTYPES.h"
+}
+
+//! \brief Preporcessor definitions
+/*!
+ add HAIRAPI_STATIC preprocessor definitionsif you
+ are linking within static hairAPI.lib
+*/
+#if defined(WIN32) && !defined(HAIRAPI_STATIC)
+# ifdef HAIRAPI_EXPORTS
+# define HAIRAPI __declspec(dllexport)
+# else
+# define HAIRAPI __declspec(dllimport)
+# endif
+#else
+# define HAIRAPI
+#endif
+
+//
+//! \brief Instance oritented and Voxel orientead workflows are possible withi hairSDK
+/*!
+ 1) Retrieve IHairStack instance using LoadHair(char* dra_file);
+
+ a) Render instance (node) oriented workflow
+ 2) Retrive IHariNode by shave stack index IHairNode* hairNode = hairStack->GetHairNodeByID(stack_index);
+ 3) Retrive IHairVoxesl associated with node IHairVoxel* voxel = hairNode->GetVoxel(idx);
+ 4) Retrieve boudind boxes, hair types or uvsets from IHairVoxel using corespondent methods
+
+ b) Voxel oriented workflow
+ 2) Retrieve voxels by need from IHairStack using IHairVoxel* voxel = hairStack->GetVoxel(...) methods
+ 3) Retrieve boudind boxes, hair types or uvsets from IHairVoxel using corespondent methods
+*/
+
+class IHairStack;
+
+//! \brief Fuction loads data from DRA file and creates new instance of IHairStack.
+/*!
+ Any works is started by calling this function.
+
+ \param[in] dra_file - The full path to dra file.
+ \return An isntace of IHairStack.
+*/
+HAIRAPI IHairStack* LoadHair(char* dra_file, bool needYZswap = false);
+
+//! \brief Fuction new instance of IHairStack from DRA data
+/*!
+ Any works is started by calling this function.
+
+ \param[in] dra_data - DRA data.
+ \param[in] data_size - the size in bytes of data
+ \return An isntace of IHairStack.
+*/
+HAIRAPI IHairStack* LoadHair(void* dra_data, long data_size, bool needYZswap = false);
+
+
+
+//! \brief A warapper for HAIRTYPE structure.
+/*! No need to call SHAVE2init/free_hairtype(...) -
+ class consructor and destructor cares about it.
+*/
+class HairType : public HAIRTYPE {
+public:
+ IHairStack* owner;
+ bool squirrel;
+
+ //! \brief Class contsructor
+ /*!
+ \param[in] init - Set 'true' if HAIRTYPE shold be initalized, 'true' by defult.
+ */
+ HAIRAPI HairType(bool init = true);
+
+ //! \brief Class desctuctor
+ /*!
+ Releases HAIRTYPE data
+ */
+ HAIRAPI ~HairType();
+
+
+
+ //! \brief Retrieves the number of hair verts.
+ /*!
+ \return The number of hair verts.
+ */
+ int GetNumVerts() const;
+
+ //! \brief Retrives vertex index by face_list_idx .
+ /*!
+ \return vertex index can be used in GetVert.
+
+ \param[in] face_list_idx - is value can vary from v_start to v_end retrived by GetFace.
+ */
+ int GetFaceVert(int face_list_idx ) const;
+
+
+ //! \brief Retrives location of specified hair vertex.
+ /*!
+ The world space location is retrieved.
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve location for.
+
+ \param[out] x - The 'x' coordinate of specified vertex in world space.
+ \param[out] y - The 'y' coordinate of specified vertex in world space.
+ \param[out] z - The 'z' coordinate of specified vertex in world space.
+ */
+ void GetVert (int vertidx, float& x, float& y, float& z) const;
+
+ //! \brief Retrives uv coordinates at specified vertex.
+ /*!
+ \param[in] vertidx - The index of vert to retrieve uvs for.
+
+ \param[out] u - The 'u' coordinate of specified vertex.
+ \param[out] v - The 'v' coordinate of specified vertex.
+ \param[out] w - Not used, the value is zero.
+ */
+ void GetUV (int vertidx, float& u, float& v, float& w) const;
+
+ //! \brief Retrives velocity of specified hair vertex.
+ /*!
+ Speed vector in world space is retrieved.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve the speed for.
+ \param[out] x - The x-component of speed vector.
+ \param[out] y - The y-component of speed vector.
+ \param[out] z - The z-component of speed vector.
+ */
+ void GetVelocity(int vertidx, float& x, float& y, float& z) const;
+
+
+ //! \brief Retrieves the number of strands.
+ /*!
+ \return Number of strands.
+ */
+ int GetNumStrands() const;
+
+ //! \brief Retrives the vertex indicies range for specified strand.
+ /*!
+ \param[in] strandidx - The strand index.
+ \param[out] v_start - The first vertex's index of specified strand.
+ \param[out] v_end - The index of the last vertex of strand.
+ */
+ void GetStrand(int strandidx, int& v_start, int& v_end) const;
+
+ //! \brief Retrieves the number of faces. Used for instanced hair.
+ /*!
+ \return Number of faces.
+ */
+ int GetNumFaces() const;
+
+ //! \brief Retrives the vertex indicies range for specified face. Used for instanced hair.
+ /*!
+ \param[in] faceidx - The face index.
+ \param[out] v_start - The first vertex's index of specified face.
+ \param[out] v_end - The index of the last vertex of face.
+ */
+ void GetFace(int faceidx, int& v_start, int& v_end) const;
+
+ //! \brief Idicates that color does not change along strand.
+ /*!
+ \param[in] strandidx - The strand index to perform the check for.
+ \return 'true' if color is constant along the strand otherwise 'false'
+ */
+ bool IsColorConst(int strandidx) const;
+
+ //! \brief Retrives the root color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ void GetRootColor(int strandidx, float& r, float& g, float& b) const;
+
+ //! \brief Retrives the tip color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ void GetTipColor (int strandidx, float& r, float& g, float& b) const;
+
+ //! \brief Retrives the color for specified knot (vertex) of the strand.
+ /*!
+ Interpolation is not performed if color is constant along the strand.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] knot_idx - Knot index in range [0; v_end-v_start]
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ //! See /see HairType::GetStrand for knot indexing details.
+ void GetVertColor(int strandidx, int knot_idx, float& r, float& g, float& b) const;
+
+ //! \brief Retrives interplolated color along the strand.
+ /*!
+ Interpolation is not performed if color is constant.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] t - Value in range [0.0; 1.0] to define location along the strand. 0 is correspondent to root.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ void GetColor (int strandidx, float t, float& r, float& g, float& b) const;
+
+ //! \brief Retrieves surface normal where specified strand is grown.
+ /*!
+ Normal vector in world space is retrieved.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive normal for.
+ \param[out] x - The x-component of normal vector.
+ \param[out] y - The y-component of normal vector.
+ \param[out] z - The z-component of normal vector.
+ */
+ void GetSurfNormal(int strandidx, float& x, float& y, float& z) const;
+
+ //! \brief Retrives the glossines value for specified strand.
+ /*!
+ \param[in] strandidx - The index of the strand to retrieve for.
+ /retrun Glossiness value.
+ */
+ float GetStrandGlossiness(int strandidx) const;
+
+ //! \brief Retrives the specular level for specified strand.
+ /*
+ \param[in] strandidx - The index of the strand to retrieve value for.
+ /retrun Specular level value.
+ */
+ float GetStrandSpecLevel(int strandidx) const;
+
+ //! \brief Retrives the opacity value for specified strand.
+ /*!
+ \param[in] strandidx - The index of the strand to retrieve for.
+ /retrun Opacity value.
+ */
+ float GetStrandOpacity(int strandidx) const;
+
+ //! \brief Retrieves the Ambient/Diffuse ratio for specified strand.
+ /*!
+ \param[in] strandidx- The index of the strand to retrieve for.
+ /retrun The Ambient/Diff ratio.
+ */
+ float GetStrandAmbDiff(int strandidx) const;
+};
+
+
+//! /bief A warapper class for UVSETS structure.
+/*!
+ No need to call SHAVE2init/free_UVs(...) -
+ consructor and destructor and destructor cares about it.
+*/
+class HairUVs : public UVSETS {
+public:
+
+ //! \brief Class constructor.
+ /*!
+ \param[in] init - Set 'true' if UVSETS shold be initalized, 'true' by defult.
+ */
+ HAIRAPI HairUVs(bool init = true);
+
+ //! \brief Class descructor.
+ /*!
+ Releases UVSETS data.
+ */
+ HAIRAPI ~HairUVs();
+};
+
+
+//! \brief Provides access to HairType and HairUVs of voxel.
+/*!
+ Hair is disributed in uniform grid. Hair data can be retrived
+ for each voxel in grid. Voxels associated with certain hair node
+ can be retrived via IHairNode class.
+*/
+class IHairVoxel {
+public:
+
+ //! \brief Queries voxel for hair presnse.
+ /*!
+ \return 'true' if there is hair in voxel, otherwise 'false'.
+ */
+ virtual HAIRAPI bool HasHair() const = 0;
+
+ //! \brief Queries how hair was loaded. And is it associated with IHairNode.
+ /*!
+ \return 'true' if voxel was retrieved using SHAVE2import_mem_archive_voxel_by_node(...)
+ 'false' if voxel was retrived using SHAVE2import_mem_archive_voxel(...) and holds HairType
+ for all the nodes in voxel.
+ */
+ virtual HAIRAPI bool IsNodeVoxel() const = 0;
+
+
+ //! \brief Returns node id if current voxel si node-voxel, otherwise returns -1.
+ /*
+ \return Node id voxel is associated with. Or -1 if IsNodeVoxel() is 'false'.
+ */
+ //! /see IHairVoxel::IsNodeVoxel
+ virtual HAIRAPI int GetNodeID() const = 0;
+
+ //! \brief Retrieves bounding box for the voxel if it is not empty.
+ /*!
+ \param[out] pmin - Bounding box minimum.
+ \param[out] pmax - Bounding box maximum.
+ \return 'true' if not epmty and bbox was retrieved succesfully, otherwise 'false'.
+ */
+ virtual HAIRAPI bool GetBbox(VERT& pmin, VERT& pmax) const = 0;
+
+ //! \brief Retrieves HairType for a voxel or for node in voxel.
+ /*!
+ \return NULL of voxel is empy, otherwise actuall HairType.
+ */
+ virtual HAIRAPI const HairType& GetHair(/*bool isShadow = false*/) = 0;
+
+ //! \brief Retrieves HairUVs for a voxel or for node in voxel.
+ /*!
+ \return NULL of voxel is empy, otherwise actuall HairUVs
+ */
+ virtual HAIRAPI const HairUVs& GetUVs (/*bool isShadow = false*/) = 0;
+
+ /////////////////////////////////////////////////////////////////////////
+ // These methods retrieve data from voxel's HairType
+ ////////////////////////////////////////////////////////////////////////
+
+
+ //! \brief Retrieves the number of hair verts.
+ /*!
+ \return The number of hair verts.
+ */
+ virtual HAIRAPI int GetNumVerts() const = 0;
+
+ //! \brief Retrives location of specified hair vertex.
+ /*!
+ The world space location is retrieved.
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve location for.
+
+ \param[out] x - The 'x' coordinate of specified vertex in world space.
+ \param[out] y - The 'y' coordinate of specified vertex in world space.
+ \param[out] z - The 'z' coordinate of specified vertex in world space.
+ */
+ virtual HAIRAPI void GetVert (int vertidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrives velocity of specified hair vertex.
+ /*!
+ Speed vector in world space is retrieved.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve the speed for.
+ \param[out] x - The x-component of speed vector.
+ \param[out] y - The y-component of speed vector.
+ \param[out] z - The z-component of speed vector.
+ */
+ virtual HAIRAPI void GetVelocity(int vertidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrieves the number of strands in voxel.
+ /*!
+ \return Number of strands.
+ */
+ virtual HAIRAPI int GetNumStrands() const = 0;
+
+ //! \brief Retrives the vertex indicies range for specified strand.
+ /*!
+ \param[in] strandidx - The strand index.
+ \param[out] v_start - The first vertex's index of specified strand.
+ \param[out] v_end - The index of the last vertex of strand.
+ */
+ virtual HAIRAPI void GetStrand(int strandidx, int& v_start, int& v_end) const = 0;
+
+ //! \brief Retrieves the number of faces in voxel. Used for instanced hair.
+ /*!
+ \return Number of faces.
+ */
+ virtual HAIRAPI int GetNumFaces() const = 0;
+
+ //! \brief Retrives the vertex indicies range for specified face. Used for instanced hair.
+ /*!
+ \param[in] faceidx - The face index.
+ \param[out] v_start - The first vertex's index of specified face.
+ \param[out] v_end - The index of the last vertex of face.
+ */
+ virtual HAIRAPI void GetFace(int faceidx, int& v_start, int& v_end) const = 0;
+
+ //! \brief Idicates that color does not change along strand.
+ /*!
+ \param[in] strandidx - The strand index to perform the check for.
+ \return 'true' if color is constant along the strand otherwise 'false'
+ */
+ virtual HAIRAPI bool IsColorConst(int strandidx) const = 0;
+
+ //! \brief Retrives the root color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetRootColor(int strandidx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives the tip color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetTipColor (int strandidx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives the color for specified knot (vertex) of the strand.
+ /*!
+ Interpolation is not performed if color is constant along the strand.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] knot_idx - Knot index in range [0; v_end-v_start]
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ //! See /see IHairVoxel::GetStrand for knot indexing details.
+ virtual HAIRAPI void GetVertColor(int strandidx, int knot_idx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives interplolated color along the strand.
+ /*!
+ Interpolation is not performed if color is constant.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] t - Value in range [0.0; 1.0] to define location along the strand. 0 is correspondent to root.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetColor (int strandidx, float t, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrieves surface normal where specified strand is grown.
+ /*!
+ Normal vector in world space is retrieved.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive normal for.
+ \param[out] x - The x-component of normal vector.
+ \param[out] y - The y-component of normal vector.
+ \param[out] z - The z-component of normal vector.
+ */
+ virtual HAIRAPI void GetSurfNormal(int strandidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrives the glossines value for specified strand.
+ /*!
+ \param[in] strandidx - The index of the strand to retrieve for.
+ /retrun Glossiness value.
+ */
+ virtual HAIRAPI float GetStrandGlossiness(int strandidx) const = 0;
+
+ //! \brief Retrives the specular level for specified strand.
+ /*
+ \param[in] strandidx - The index of the strand to retrieve value for.
+ /retrun Specular level value.
+ */
+ virtual HAIRAPI float GetStrandSpecLevel(int strandidx) const = 0;
+
+ //! \brief Retrives the opacity value for specified strand.
+ /*!
+ \param[in] strandidx - The index of the strand to retrieve for.
+ /retrun Opacity value.
+ */
+ virtual HAIRAPI float GetStrandOpacity(int strandidx) const = 0;
+
+ //! \brief Retrieves the Ambient/Diffuse ratio for specified strand.
+ /*!
+ \param[in] strandidx- The index of the strand to retrieve for.
+ /retrun The Ambient/Diff ratio.
+ */
+ virtual HAIRAPI float GetStrandAmbDiff(int strandidx) const = 0;
+
+};
+
+
+//! \brief Provies access hair data and IHairVoxels associated with the current node.
+/*!
+ All vertex or strand Get... methods are quering all the voxels
+ associated with current node.
+*/
+class IHairNode {
+public:
+ virtual ~IHairNode(){}
+
+ //! brief Retrieves the version of Shave Engine.
+ /*!
+ Should return the sting in 'X.XvXX' format.
+ */
+ static HAIRAPI char* GetVersion();
+
+ //! \brief Retrives bounding box of IHairNode.
+ /*!
+ Bounding box retrieved is equal to union of voxels' bounding boxes it occupies.
+
+ \param[out] pmin - Bounding box minimum.
+ \param[out] pmax - Bounding box maximum.
+ \return Normaly 'true' if node has hair, 'false' otherwise.
+ */
+ virtual HAIRAPI bool GetBbox(VERT& pmin, VERT& pmax) const = 0;
+
+
+ //! brief Retrieves current node index in hair stack.
+ /*!
+ \return Hair node stack index.
+ */
+ virtual HAIRAPI int GetStackID() const = 0;
+
+ //! \brief Retrieves the number of voxels node occupies.
+ /*!
+ \return Number of voxels.
+ */
+ virtual HAIRAPI int GetNumVoxels()const = 0;
+
+ //! \brief Retrives IHairVoxel(s) node occupies
+ /*!
+ \param[in] i - Index of voxel in range [0; GetNumVoxels()-1].
+ \return Pointer to one of the voxels. Note: do not delete these instnces - IHairNode cares about it
+ */
+ virtual HAIRAPI IHairVoxel* GetVoxel(int i) const = 0;
+
+ /////////////////////////////////////////////////////////////////////////
+ // These methods retrieve data from node's voxels
+ ////////////////////////////////////////////////////////////////////////
+
+ //! \brief Retrieves the number of hair verts in the node.
+ /*!
+ \return The number of hair verts.
+ */
+ virtual HAIRAPI int GetNumVerts() const = 0;
+
+ //! \brief Retrives location of specified hair vertex.
+ /*!
+ The world space location is retrieved.
+
+ All the voxels node occupies are taken into account.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve location for.
+
+ \param[out] x - The 'x' coordinate of specified vertex in world space.
+ \param[out] y - The 'y' coordinate of specified vertex in world space.
+ \param[out] z - The 'z' coordinate of specified vertex in world space.
+ */
+ virtual HAIRAPI void GetVert (int vertidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrives velocity of specified hair vertex.
+ /*!
+ Speed vector in world space is retrieved.
+
+ All the voxels node occupies are taken into account.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] vertidx - The index of vert to retrieve the speed for.
+ \param[out] x - The x-component of speed vector.
+ \param[out] y - The y-component of speed vector.
+ \param[out] z - The z-component of speed vector.
+ */
+ virtual HAIRAPI void GetVelocity(int vertidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrieves the number of strands node has.
+ /*!
+ All the voxels node occupies are taken into account.
+
+ \return Number of strands.
+ */
+ virtual HAIRAPI int GetNumStrands() const = 0;
+
+ //! \brief Retrives the vertex indicies range for specified strand.
+ /*!
+ All the voxels node occupies are taken into account.
+
+ \param[in] strandidx - The strand index.
+ \param[out] v_start - The first vertex's index of specified strand.
+ \param[out] v_end - The index of the last vertex of strand.
+ */
+ virtual HAIRAPI void GetStrand(int strandidx, int& v_start, int& v_end) const = 0;
+
+ //! \brief Retrieves the number of faces node has. Used for instanced hair.
+ /*!
+ All the voxels node occupies are taken into account.
+
+ \return Number of faces.
+ */
+ virtual HAIRAPI int GetNumFaces() const = 0;
+
+ //! \brief Retrives the vertex indicies range for specified face. Used for instanced hair.
+ /*!
+ All the voxels node occupies are taken into account.
+
+ \param[in] faceidx - The face index.
+ \param[out] v_start - The first vertex's index of specified face.
+ \param[out] v_end - The index of the last vertex of face.
+ */
+ virtual HAIRAPI void GetFace(int faceidx, int& v_start, int& v_end) const = 0;
+
+ //! \brief Idicates that color does not change along the specified strand.
+ /*!
+ \param[in] strandidx - The strand index to perform the check for.
+ \return 'true' if color is constant along the strand otherwise 'false'
+ */
+ virtual HAIRAPI bool IsColorConst(int strandidx) const = 0;
+
+ //! \brief Retrives the tip color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetRootColor(int strandidx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives the tip color of specified strand.
+ /*!
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The stand idnex to rentrive color for.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetTipColor (int strandidx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives interplolated color along the strand.
+ /*!
+ Interpolation is not performed if color is constant.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] t - Value in range [0.0; 1.0] to define location along the strand. 0 is correspondent to root.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetVertColor(int strandidx, int knot_idx, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrives interplolated color along the strand.
+ /*!
+ Interpolation is not performed if color is constant.
+
+ hairSDK does not use application dependent classes like 3ds Max's Color
+ so colors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive color for.
+ \param[in] t - Value in range [0.0; 1.0] to define location along the strand. 0 is correspondent to root.
+ \param[out] r - Red color component.
+ \param[out] g - Green color component.
+ \param[out] b - Blue color component.
+ */
+ virtual HAIRAPI void GetColor (int strandidx, float t, float& r, float& g, float& b) const = 0;
+
+ //! \brief Retrieves surface normal where specified strand is grown.
+ /*!
+ Normal vector in world space is retrieved.
+
+ hairSDK does not use application dependent classes like 3ds Max's Point3
+ so vectors are retrived by components.
+
+ \param[in] strandidx - The strand idnex to rentrive normal for.
+ \param[out] x - The x-component of normal vector.
+ \param[out] y - The y-component of normal vector.
+ \param[out] z - The z-component of normal vector.
+ */
+ virtual HAIRAPI void GetSurfNormal(int strandidx, float& x, float& y, float& z) const = 0;
+
+ //! \brief Retrives the specular level for specified strand.
+ /*
+ \param[in] strandidx - The index of the strand to retrieve value for.
+ /retrun Specular level value.
+ */
+ virtual HAIRAPI float GetStrandGlossiness(int strandidx) const = 0;
+
+ //! \brief Retrives the specular level for specified strand.
+ /*
+ \param[in] strandidx - The index of the strand to retrieve value for.
+ /retrun Specular level value.
+ */
+ virtual HAIRAPI float GetStrandSpecLevel(int strandidx) const = 0;
+
+ //! \brief Retrives the opacity value for specified strand.
+ /*!
+ \param[in] strandidx - The index of the strand to retrieve for.
+ /retrun Opacity value.
+ */
+ virtual HAIRAPI float GetStrandOpacity(int strandidx) const = 0;
+
+ //! \brief Retrieves the Ambient/Diffuse ratio for specified strand.
+ /*!
+ \param[in] strandidx- The index of the strand to retrieve for.
+ /retrun The Ambient/Diff ratio.
+ */
+ virtual HAIRAPI float GetStrandAmbDiff(int strandidx) const = 0;
+
+};
+
+
+//! \brief Provies access to IHairNodes and IHairVoxels
+/*!
+ Instance of this class is create by LoadHair(...) function.
+ Then you can choose the workflow appropriate for you and
+ and work with hair on per-node or per-voxel base.
+*/
+class IHairStack {
+public:
+ virtual HAIRAPI ~IHairStack(){}
+
+ //! brief Retrieves the version of Shave Engine.
+ /*!
+ Should return the sting in 'X.XvXX' format.
+ */
+ static HAIRAPI char* GetVersion();
+
+ //! brief Retrieves DRA file name associated with stack.
+ /*!
+ Should return the same with passed to LoadHair.
+ */
+ virtual HAIRAPI char* GetDRAname() const = 0;
+
+ //! \brief Returns total number of voxels (res*res*res) in the stack.
+ /*!
+ \return The number of voxels in the stack.
+ */
+ virtual HAIRAPI int GetNumVoxels() const = 0;
+
+ //! \brief Retrieves the voxel resolution.
+ /*!
+ \return The voxel resolution. So numvoxels = res*res*res
+ */
+ virtual HAIRAPI int GetVoxelRes() const = 0;
+
+ //! \brief Retrieves IHairVoxel by grid indicies.
+ /*!
+ \param[in] vox_x - Voxel's x-index in the grid in range [0, voxel_resolution - 1].
+ \param[in] vox_y - Voxel's y-index in the grid in range [0, voxel_resolution - 1].
+ \param[in] vox_z - Voxel's z-index in the grid in range [0, voxel_resolution - 1].
+ \return Pointer to IHairVoxel instance. You should not delete these instances, IHariStack will do it.
+ */
+ virtual HAIRAPI IHairVoxel* GetHairVoxel(int vox_x, int vox_y, int vox_z) = 0;
+
+ //! \brief Retrieves IHairVoxel by index.
+ /*!
+ \param[in] vox_index - Voxel's index in the grid in range [0, num_voxels - 1].
+ \return Pointer to IHairVoxel instance. You should not delete these instances, IHairStack will do it.
+ */
+ virtual HAIRAPI IHairVoxel* GetHairVoxel(int vox_index) = 0;
+
+ //! \brief Retrieves IHairNode by its stack index.
+ /*!
+ \param[in] The stack index of node to retrieve.
+ \return Pointer to IHairNode instance. You should not delete these insntances, IHairStack will do it.
+ */
+ virtual HAIRAPI IHairNode* GetHairNodeByID(int stack_id, bool squirrel = false) = 0;
+
+
+ //! \brief Places the thread lock (you do not need to call this routine direcly).
+ virtual void Lock() = 0;
+
+ //! \brief Removes the thread lock (you do not need to call this routine direcly).
+ virtual void UnLock() = 0;
+};
+
+
+
+#endif //end of_SHAVE2_API_H_
diff --git a/vrayPlug/plugin/hairAPIimp.cpp b/vrayPlug/plugin/hairAPIimp.cpp
new file mode 100644
index 0000000..8253672
--- /dev/null
+++ b/vrayPlug/plugin/hairAPIimp.cpp
@@ -0,0 +1,1464 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: hairAPIImp.cpp -- iplementation file
+
+ DESCRIPTION: Implementation of C++ Intefraces for SHAVE2 functions
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-08-2008
+
+ *>
+ **********************************************************************/
+
+#include "hairAPIimp.h"
+#include "assert.h"
+
+#include "shaveVrayPlugin.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#define fileno _fileno
+#define fstat _fstat
+typedef struct _stat StatType;
+#else
+#include <unistd.h>
+typedef struct stat StatType;
+#endif
+
+
+
+
+
+extern "C"
+{
+#include "shaveSDKFUNCS2.h"
+//
+// Some shave stuff need to implement
+//
+extern VERT SHAVE2apply_GI(VERT vv, CURVEINFO *ci)
+{
+ VERT retValue;
+ retValue.x = 0.0f;
+ retValue.y = 0.0f;
+ retValue.z = 0.0f;
+ return retValue;
+}
+
+extern void SHAVE2draw_tile_callback(VERT *a,VERT *b)
+{
+}
+
+} //end "C"
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| Creates an instace of hairStack |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+static bool doNeedYZswap = false;
+
+HAIRAPI IHairStack* LoadHair(char* dra_file, bool needYZswap)
+{
+ return new HairStack(dra_file,needYZswap);
+}
+
+HAIRAPI IHairStack* LoadHair(void* dra_data, long data_size, bool needYZswap)
+{
+ return new HairStack(dra_data,data_size,needYZswap);
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| HairStack wrapper |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+char* IHairStack::GetVersion()
+{
+ return SHAVE2query_version();
+}
+void init_threads( void );
+
+HAIRAPI HairStack::HairStack(char* fname, bool needYZswap)
+{
+#ifdef WIN32
+ InitializeCriticalSection(&csect);
+#else
+ pthread_mutex_init( &mutex, NULL );
+#endif
+
+ //its called in shaveVrayPlugin::renderBegin
+ //SHAVE2init(); // uncommented joe - oct 10
+
+ LOGMSG("SHAVE","SHAVE2clear_stack");
+ SHAVE2clear_stack(); // uncommented joe - oct 10
+
+ //init_threads(); // uncommented joe - oct 10
+
+ _needyzswap() = needYZswap;
+ _draname() = NULL;
+ if(fname)
+ {
+ Init(fname);
+ }
+}
+
+HAIRAPI HairStack::HairStack(void* bdata, long size, bool needYZswap)
+{
+#ifdef WIN32
+ InitializeCriticalSection(&csect);
+#else
+ pthread_mutex_init( &mutex, NULL );
+#endif
+
+ //its called in shaveVrayPlugin::renderBegin
+ //SHAVE2init(); // uncommented joe - oct 10
+
+ LOGMSG("SHAVE","SHAVE2clear_stack");
+ SHAVE2clear_stack(); // uncommented joe - oct 10
+
+ //init_threads(); // uncommented joe - oct 10
+
+ _needyzswap() = needYZswap;
+ _draname() = NULL;
+ if(bdata && size > 0)
+ {
+ Init(bdata,size);
+ }
+}
+
+HAIRAPI HairStack::~HairStack()
+{
+ Clear();
+
+ if(draname())
+ free(draname());
+
+ LOGMSG("SHAVE","SHAVE2clear_stack");
+ SHAVE2clear_stack(); //added
+
+ //called in shaveVrayPlugin::renderEnd
+ //SHAVE2cleanup(); // uncommented joe - oct 10
+
+#ifdef WIN32
+ DeleteCriticalSection(&csect);
+#else
+ pthread_mutex_destroy( &mutex );
+#endif
+}
+
+
+/*
+| from IHairStack
+*/
+HAIRAPI bool HairStack::Init(char* filename)
+{
+ LOGMSG("SHAVE", "HairStack::Init");
+
+ size_t len = strlen(filename) + 5;
+ _draname() = (char*)malloc(len);
+ memset(draname(),0,len);
+ sprintf(draname(),"%s",filename);
+
+ LOGMSGS("SHAVE", "HairStack: dra file ",draname());
+
+#ifdef USE_MEMFILE
+ init_MEMFILE2(&_mem(),0);
+ FILE* draFile = fopen(draname(), "r+b");
+ if(!draFile)
+ {
+ LOGMSGS("SHAVE","HairStack: can not open dra file ",draname());
+ return false;
+ }
+
+ //Get the size of the DRA file.
+
+ StatType fileInfo;
+ fstat(fileno(draFile), &fileInfo);
+ if(fileInfo.st_size == 0)
+ {
+ LOGMSGS("SHAVE", "HairStack: can not read dra file ",draname());
+ return false;
+ }
+ _mem().size = fileInfo.st_size;
+ _mem().data = (char*)malloc(mem().size);
+
+
+ //size_t nread = fread(&_mem().data,1,mem().size,draFile);
+ int sum = 0;
+ int c;
+ int p = 0;
+ while ((c = fgetc(draFile)) != EOF)
+ {
+ _mem().data[p] = c;
+ p++;
+ sum+=c;
+ }
+ fclose(draFile);
+ if(p != mem().size)
+ {
+ char buf[100]; sprintf(buf,"(bytes read: %i expected: %li)",p,mem().size);
+ LOGMSGS("SHAVE", "HairStack: error reading DRA file ",buf);
+ free_MEMFILE2(&_mem());
+ return false;
+ }
+
+ LOGMSGI("SHAVE", "HairStack: bytes read ",p);
+ //printf("SHAVE> MEMFILE ID:%i data:%p, pos:%i size:%i\n",mem().ID, mem().data, mem().pos, mem().size );
+ LOGMSGI("SHAVE", "shaveVrayInstance: (debug) checksum ", (int)sum);
+
+ Lock();
+ try
+ {
+ LOGMSG("SHAVE", "SHAVE2init_hairstack_from_mem_archive");
+ _voxres() = SHAVE2init_hairstack_from_mem_archive(&_mem());
+// SHAVEprint_engine2();
+ }
+ catch (...)
+ {
+ LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_mem_archive");
+ _voxres() = -1;
+ }
+ UnLock();
+#else
+ Lock();
+ try
+ {
+ LOGMSG("SHAVE", "SHAVE2init_hairstack_from_archive");
+ _voxres() = SHAVE2init_hairstack_from_archive(draname());
+ }
+ catch (...)
+ {
+ LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_archive");
+ _voxres() = -1;
+ }
+ UnLock();
+#endif
+
+
+ if(voxres() == -1)
+ {
+ return false;
+ }
+ if(voxres() != 0)
+ {
+ _voxels().resize(voxres()*voxres()*voxres());
+ for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++)
+ {
+ _voxel(i) = NULL;
+ }
+ }
+ LOGMSG("SHAVE", "HairStack::Init - OK");
+ return true;
+}
+
+/*
+| from IHairStack
+*/
+HAIRAPI bool HairStack::Init(void* bdata, long size)
+{
+ LOGMSG("SHAVE", "HairStack::Init");
+ LOGMSGI("SHAVE", "HairStack: data size ",(int)size);
+
+ init_MEMFILE2(&_mem(),0);
+ _mem().size = size;
+ _mem().data = (char*)bdata;
+
+ Lock();
+ try
+ {
+ LOGMSG("SHAVE", "SHAVE2init_hairstack_from_mem_archive");
+ _voxres() = SHAVE2init_hairstack_from_mem_archive(&_mem());
+ }
+ catch (...)
+ {
+ LOGMSG("SHAVE", "exception occured in SHAVE2init_hairstack_from_mem_archive");
+ _voxres() = -1;
+ }
+ UnLock();
+
+
+ if(voxres() == -1)
+ {
+ return false;
+ }
+ if(voxres() != 0)
+ {
+ _voxels().resize(voxres()*voxres()*voxres());
+ for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++)
+ {
+ _voxel(i) = NULL;
+ }
+ }
+ LOGMSG("SHAVE", "HairStack::Init - OK");
+ return true;
+}
+/*
+| from IHairStack
+*/
+HAIRAPI void HairStack::Clear()
+{
+ LOGMSG("SHAVE", "HairStack::Clear");
+
+ for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++)
+ {
+ if(voxel(i))
+ {
+ delete voxel(i);
+ _voxel(i) = NULL;
+ }
+ }
+ _voxels().clear();
+ _voxres() = 0;
+
+ for(unsigned int i = 0; i < (unsigned int)nodes().size(); i++)
+ {
+ if(node(i))
+ {
+ delete node(i);
+ _node(i) = NULL;
+ }
+ }
+ _nodes().clear();
+
+ LOGMSG("SHAVE", "SHAVE2clear_stack");
+
+ Lock();
+ SHAVE2clear_stack();
+ UnLock();
+
+ LOGMSG("SHAVE", "HairStack::Clear - OK");
+}
+/*
+| from IHairStack
+*/
+HAIRAPI char* HairStack::GetDRAname() const
+{
+ return draname();
+}
+/*
+| from IHairStack
+*/
+HAIRAPI int HairStack::GetNumVoxels() const
+{
+ return (int)voxels().size();
+}
+/*
+| from IHairStack
+*/
+HAIRAPI int HairStack::GetVoxelRes() const
+{
+ return voxres();
+}
+/*
+| from IHairStack
+*/
+HAIRAPI IHairVoxel* HairStack::GetHairVoxel(int x, int y, int z)
+{
+ int idx = 0;
+ int nvoxels = (int)voxels().size();
+ if(nvoxels == 0)
+ return NULL;
+
+ if(voxelIDXformXYZ(idx,x,y,z) && idx < nvoxels)
+ {
+ if(!voxel(idx))
+ {
+ VERT ppMax;
+ VERT ppMin;
+
+ VERT pMax;
+ VERT pMin;
+
+ Lock();
+
+#ifdef USE_MEMFILE
+ LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox");
+ if(SHAVE2import_mem_archive_voxel_bbox( &_mem(), x, y, z, &ppMin, &ppMax ))
+#else
+ LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox");
+ if(SHAVE2import_archive_voxel_bbox( draname(), x, y, z, &ppMin, &ppMax ))
+#endif
+ {
+ if(needyzswap())
+ {
+ pMin.x = ppMin.x;
+ pMin.y = -ppMax.z;
+ pMin.z = ppMin.y;
+
+ pMax.x = ppMax.x;
+ pMax.y = -ppMin.z;
+ pMax.z = ppMax.y;
+ }
+ else
+ {
+ pMin = ppMin;
+ pMax = ppMax;
+ }
+ _voxel(idx) = new HairVoxel(this, pMin, pMax, x, y, z, false);
+ }
+ else
+ {
+ //no hair in voxel
+ _voxel(idx) = new HairVoxel();
+ }
+ UnLock();
+ }
+ return voxel(idx);
+ }
+ return NULL;
+}
+/*
+| from IHairStack
+*/
+HAIRAPI IHairVoxel* HairStack::GetHairVoxel(int idx)
+{
+ int nvoxels = (int)voxels().size();
+ if(nvoxels == 0)
+ return NULL;
+
+ if(idx < nvoxels)
+ {
+ if(!voxel(idx) )
+ {
+ VERT ppMax;
+ VERT ppMin;
+
+ VERT pMax;
+ VERT pMin;
+
+ int x, y, z;
+ if(voxelXYZformIDX(idx,x,y,z))
+ {
+ Lock();
+
+#ifdef USE_MEMFILE
+ LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox");
+ if(SHAVE2import_mem_archive_voxel_bbox( &_mem(), x, y, z, &ppMin, &ppMax))
+#else
+ LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox");
+ if(SHAVE2import_archive_voxel_bbox( draname(), x, y, z, &ppMin, &ppMax))
+#endif
+ {
+ if(needyzswap())
+ {
+ pMin.x = ppMin.x;
+ pMin.y = -ppMax.z;
+ pMin.z = ppMin.y;
+
+ pMax.x = ppMax.x;
+ pMax.y = -ppMin.z;
+ pMax.z = ppMax.y;
+ }
+ else
+ {
+ pMin = ppMin;
+ pMax = ppMax;
+ }
+
+ _voxel(idx) = new HairVoxel(this, pMin, pMax, x, y, z, false);
+ }
+ else
+ {
+ //no hair in voxel
+ _voxel(idx) = new HairVoxel();
+ }
+ UnLock();
+ }
+ }
+ return voxel(idx);
+ }
+ return NULL;
+}
+/*
+| from IHairStack
+*/
+HAIRAPI IHairNode* HairStack::GetHairNodeByID (int node_index, bool squirrel)
+{
+ for(unsigned int i = 0; i < nodes().size(); i++)
+ if(node(i) && node(i)->GetStackID() == node_index)
+ return node(i);
+
+ HairNode* hnode = new HairNode(this, node_index,squirrel);
+ if(hnode->GetNumVoxels() == 0)
+ {
+ delete hnode;
+ return NULL;
+ }
+ _nodes().push_back(hnode);
+ return hnode;
+}
+/*
+| from IHairStack
+*/
+void HairStack::Lock()
+{
+#ifdef WIN32
+ EnterCriticalSection(&csect);
+#else
+ pthread_mutex_lock( &mutex );
+#endif
+}
+/*
+| from IHairStack
+*/
+void HairStack::UnLock()
+{
+#ifdef WIN32
+ LeaveCriticalSection(&csect);
+#else
+ pthread_mutex_unlock( &mutex );
+#endif
+}
+
+bool HairStack::voxelXYZformIDX(int index, int& x, int& y, int& z)
+{
+ if(voxres() == 0)
+ {
+ x = y = z = 0;
+ return false;
+ }
+ int voxresSq = voxres()*voxres();
+
+ z = index / (voxresSq);
+ y = (index - z*voxresSq)/voxres();
+ x = index - z*voxresSq - y*voxres();
+ return true;
+}
+
+bool HairStack::voxelIDXformXYZ(int& index, int x, int y, int z)
+{
+ if(voxres() == 0)
+ {
+ index = -1;
+ return false;
+ }
+ index = z*(voxres()*voxres()) + y*voxres() + x;
+ return true;
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| HairHode wrapper |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+char* IHairNode::GetVersion()
+{
+ return SHAVE2query_version();
+}
+
+HAIRAPI HairNode::HairNode(HairStack* hstack, int stack_id, bool sqrl)
+{
+ LOGMSG("SHAVE", "HairNode ctor");
+
+ assert(hstack);
+ _stack() = hstack;
+ _stackid() = stack_id;
+ _squirrel()= sqrl;
+
+ _bboxMin().x = FLT_MAX;
+ _bboxMin().y = FLT_MAX;
+ _bboxMin().z = FLT_MAX;
+
+ _bboxMax().x = -FLT_MAX;
+ _bboxMax().y = -FLT_MAX;
+ _bboxMax().z = -FLT_MAX;
+
+ float x1 = FLT_MAX;
+ float y1 = FLT_MAX;
+ float z1 = FLT_MAX;
+
+ float x2 = -FLT_MAX;
+ float y2 = -FLT_MAX;
+ float z2 = -FLT_MAX;
+
+ if(!stack())
+ return;
+
+ int voxres = hstack->GetVoxelRes();
+
+ LOGMSGI("SHAVE", "voxres",voxres);
+
+ for(int ix = 0; ix < voxres; ix++)
+ {
+ for(int iy = 0; iy < voxres; iy++)
+ {
+ for(int iz = 0; iz < voxres; iz++)
+ {
+ VERT pMin;
+ VERT pMax;
+
+ VERT ppMin;
+ VERT ppMax;
+
+ bool hasHair;
+
+ _stack()->Lock();
+ try
+ {
+#ifdef USE_MEMFILE
+ LOGMSG("SHAVE", "SHAVE2import_mem_archive_voxel_bbox");
+ hasHair = SHAVE2import_mem_archive_voxel_bbox(
+ stack()->GetMemFile(),
+ ix,
+ iy,
+ iz,
+ &ppMin,
+ &ppMax
+ ) != 0;
+#else
+ LOGMSG("SHAVE", "SHAVE2import_archive_voxel_bbox");
+ hasHair = SHAVE2import_archive_voxel_bbox(
+ stack()->GetDRAname(),
+ ix,
+ iy,
+ iz,
+ &ppMin,
+ &ppMax
+ ) != 0;
+#endif
+ }
+ catch (...)
+ {
+ LOGMSG("SHAVE", "an exception occured in SHAVE2import(_mem_)archive_voxel_bbox");
+ hasHair = false;
+ }
+
+ _stack()->UnLock();
+
+ if(!hasHair)
+ {
+ continue;
+ }
+ if(hstack->GetNeedYZswap())
+ {
+ pMin.x = ppMin.x;
+ pMin.y = -ppMax.z;
+ pMin.z = ppMin.y;
+
+ pMax.x = ppMax.x;
+ pMax.y = -ppMin.z;
+ pMax.z = ppMax.y;
+ }
+ else
+ {
+ pMin = ppMin;
+ pMax = ppMax;
+ }
+
+ HairVoxel* vox = new HairVoxel(stack(),pMin,pMax, stackid(),ix,iy,iz,squirrel());
+ if(!vox->HasHair())
+ {
+ delete vox;
+ continue;
+ }
+ //init lookup tables
+ int vox_idx = (int)voxels().size();
+ int num_vox_verts = vox->GetNumVerts();
+ for(int i = 0; i < num_vox_verts; i++)
+ {
+ _vtovoxs().push_back(vox_idx);
+ _vtovoxVs().push_back(i);
+ }
+
+ int num_vox_strands = vox->GetNumStrands();
+ for(int i = 0; i < num_vox_strands; i++)
+ {
+ _stovoxs().push_back(vox_idx);
+ _stovoxSs().push_back(i);
+ }
+
+ //add voxel to list
+ _voxels().push_back(vox);
+
+
+ //expand bounding box
+ _bboxMin().x = bboxMin().x > pMin.x ? pMin.x : bboxMin().x;
+ _bboxMin().y = bboxMin().y > pMin.y ? pMin.y : bboxMin().y;
+ _bboxMin().z = bboxMin().z > pMin.z ? pMin.z : bboxMin().z;
+
+ _bboxMax().x = bboxMax().x < pMax.x ? pMax.x : bboxMax().x;
+ _bboxMax().y = bboxMax().y < pMax.y ? pMax.y : bboxMax().y;
+ _bboxMax().z = bboxMax().z < pMax.z ? pMax.z : bboxMax().z;
+ }
+ }
+ }
+ LOGMSG("SHAVE", "HairNode ctor - OK");
+}
+
+HAIRAPI HairNode::~HairNode()
+{
+ LOGMSG("SHAVE", "HairNode dtor");
+
+ for(unsigned int i = 0; i < (unsigned int)voxels().size(); i++)
+ {
+ if(voxel(i))
+ {
+ delete voxel(i);
+ _voxel(i) = NULL;
+ }
+ }
+ _voxels().clear();
+
+ _vtovoxs().clear();
+ _vtovoxVs().clear();
+
+ _stovoxs().clear();
+ _stovoxSs().clear();
+
+ LOGMSG("SHAVE", "HairNode dtor - OK");
+}
+
+/*
+| from IHairNode
+*/
+HAIRAPI bool HairNode::GetBbox(VERT& pmin, VERT& pmax) const
+{
+ pmin = bboxMin();
+ pmax = bboxMax();
+ return (voxels().size() > 0);
+}
+/*
+| from IHairNode
+*/
+HAIRAPI int HairNode::GetStackID() const
+{
+ return stackid();
+}
+/*
+| from IHairNode
+*/
+HAIRAPI int HairNode::GetNumVoxels()const
+{
+ return (int)voxels().size();
+}
+/*
+| from IHairNode
+*/
+HAIRAPI IHairVoxel* HairNode::GetVoxel(int i) const
+{
+ if(i < (int)voxels().size())
+ return voxel(i);
+
+ return NULL;
+}
+/*
+| from IHairNode
+*/
+int HairNode::GetNumVerts () const
+{
+ return (int)vtovoxs().size();
+}
+/*
+| from IHairNode
+*/
+int HairNode::GetNumStrands() const
+{
+ return (int)stovoxs().size();
+}
+/*
+| from IHairNode
+*/
+int HairNode::GetNumFaces() const
+{
+ return (int)stovoxs().size();
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetVert(int i, float& x, float& y, float& z) const
+{
+ int vox_idx;
+ int vert_idx;
+ vertIndexToVoxVertIndex(i,vox_idx,vert_idx);
+
+ voxel(vox_idx)->GetVert(vert_idx,x,y,z);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetVelocity(int i, float& x, float& y, float& z) const
+{
+ int vox_idx;
+ int vert_idx;
+ vertIndexToVoxVertIndex(i,vox_idx,vert_idx);
+
+ voxel(vox_idx)->GetVelocity(vert_idx,x,y,z);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetStrand(int i, int& v_start, int& v_end) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetStrand(str_idx,v_start,v_end);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetFace(int i, int& v_start, int& v_end) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetFace(str_idx,v_start,v_end);
+}
+/*
+| from IHairNode
+*/
+bool HairNode::IsColorConst (int i) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ return voxel(vox_idx)->IsColorConst(str_idx);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetRootColor (int i, float& r, float& g, float& b) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetRootColor(str_idx,r,g,b);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetTipColor(int i, float& r, float& g, float& b) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetTipColor(str_idx,r,g,b);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetVertColor(int i, int knot_idx, float& r, float& g, float& b) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetVertColor(str_idx,knot_idx,r,g,b);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetColor(int i, float t, float& r, float& g, float& b) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetColor(str_idx,t,r,g,b);
+}
+/*
+| from IHairNode
+*/
+void HairNode::GetSurfNormal(int i, float& x, float& y, float& z) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ voxel(vox_idx)->GetSurfNormal(str_idx,x,y,z);
+}
+/*
+| from IHairNode
+*/
+float HairNode::GetStrandGlossiness(int i) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ return voxel(vox_idx)->GetStrandGlossiness(str_idx);
+}
+/*
+| from IHairNode
+*/
+float HairNode::GetStrandSpecLevel(int i) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ return voxel(vox_idx)->GetStrandSpecLevel(str_idx);
+}
+
+/*
+| from IHairNode
+*/
+float HairNode::GetStrandOpacity(int i) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ return voxel(vox_idx)->GetStrandOpacity(str_idx);
+}
+/*
+| from IHairNode
+*/
+float HairNode::GetStrandAmbDiff(int i) const
+{
+ int vox_idx;
+ int str_idx;
+ strandIndexToVoxStrandIndex(i,vox_idx,str_idx);
+
+ return voxel(vox_idx)->GetStrandAmbDiff(str_idx);
+}
+
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| HairVoxel wrapper |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+HAIRAPI HairVoxel::HairVoxel()
+{
+ _stack() = NULL;
+ _hashair() = false;
+ _nodevoxel()= false;
+ _nodeindex()= -1;
+ _squirrel() = false;
+
+ _bboxMin().x = FLT_MAX;
+ _bboxMin().y = FLT_MAX;
+ _bboxMin().z = FLT_MAX;
+
+ _bboxMax().x = -FLT_MAX;
+ _bboxMax().y = -FLT_MAX;
+ _bboxMax().z = -FLT_MAX;
+
+ _hairtype().owner = NULL;
+}
+
+HAIRAPI HairVoxel::HairVoxel(HairStack* hstack,
+ const VERT& pmin, const VERT& pmax,
+ int ix, int iy, int iz,
+ bool squirr)
+{
+ LOGMSGI3("SHAVE","HairVoxel ctor",ix, iy, iz);
+
+ _stack() = hstack;
+ _hashair() = false;
+ _nodevoxel()= false;
+ _nodeindex()= -1;
+ _squirrel() = squirr;
+
+ _bboxMin() = pmin;
+ _bboxMax() = pmax;
+
+ assert(hstack);
+ if(!hstack)
+ return;
+
+ _stack()->Lock();
+#ifdef USE_MEMFILE
+ LOGMSG("SHAVE","SHAVE2import_mem_archive_voxel");
+ SHAVE2import_mem_archive_voxel( stack()->GetMemFile(), ix, iy, iz, &_hairtype(), 0);
+#else
+ LOGMSG("SHAVE","SHAVE2import_archive_voxel");
+ SHAVE2import_archive_voxel( hstack->GetDRAname(), ix, iy, iz, &_hairtype(), 0);
+#endif
+ _stack()->UnLock();
+
+ LOGMSGI("SHAVE","numfaces",hairtype().totalfaces);
+
+ _hashair() = hairtype().totalfaces != 0;
+ _hairtype().owner = hstack;
+ _hairtype().squirrel = squirrel();
+
+ LOGMSG("SHAVE","HairVoxel ctor - OK");
+}
+
+HAIRAPI HairVoxel::HairVoxel(HairStack* hstack,
+ const VERT& pmin, const VERT& pmax,
+ int stack_id, int ix, int iy, int iz,
+ bool squirr)
+{
+ LOGMSGI3("SHAVE","HairVoxel ctor2",ix, iy, iz);
+
+ _stack() = hstack;
+ _hashair() = false;
+ _nodevoxel()= true;
+ _nodeindex()= stack_id;
+
+ _squirrel() = squirr;
+
+ _bboxMin() = pmin;
+ _bboxMax() = pmax;
+
+ assert(hstack);
+ if(!hstack)
+ return;
+
+ _stack()->Lock();
+
+#ifdef USE_MEMFILE
+ LOGMSG("SHAVE","SHAVE2import_mem_archive_voxel_by_node");
+ SHAVE2import_mem_archive_voxel_by_node(stack()->GetMemFile(),ix,iy,iz,
+ &_hairtype(), &_hairuvs(),
+ 0, stack_id);
+#else
+ LOGMSG("SHAVE","SHAVE2import_archive_voxel_by_node");
+ SHAVE2import_archive_voxel_by_node(hstack->GetDRAname(),ix,iy,iz,
+ &_hairtype(), &_hairuvs(),
+ 0, stack_id);
+#endif
+ LOGMSGI("SHAVE","numfaces",hairtype().totalfaces);
+
+ _stack()->UnLock();
+
+ _hashair() = hairtype().totalfaces != 0;
+ _hairtype().owner = hstack;
+ _hairtype().squirrel = squirrel();
+
+ ////////////// debug ////////////
+ //int nv = hairtype().GetNumVerts();
+ //for(int i = 0; i < nv; i++)
+ //{
+ // float u,v,w;
+ // hairtype().GetUV(i,u,v,w);
+ // printf("uvw %f %f %f\n", u,v,w);
+ //}
+ //fflush(stdout);
+ /////////////////////////////////
+
+ LOGMSG("SHAVE","HairVoxel ctor2 - OK");
+}
+
+HAIRAPI HairVoxel::~HairVoxel()
+{
+ LOGMSG("SHAVE","HairVoxel dtor");
+ LOGMSG("SHAVE","HairVoxel dtor - OK");
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI bool HairVoxel::HasHair() const
+{
+ return hashair();
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI bool HairVoxel::IsNodeVoxel() const
+{
+ return nodevoxel();
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI int HairVoxel::GetNodeID(void) const
+{
+ return nodeindex();
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI bool HairVoxel::GetBbox(VERT& pmin, VERT& pmax) const
+{
+ pmin = bboxMin();
+ pmax = bboxMax();
+
+ return hashair();
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI const HairType& HairVoxel::GetHair(/*bool isShadow*/)
+{
+ return hairtype();
+}
+/*
+| from IHairVoxel
+*/
+HAIRAPI const HairUVs& HairVoxel::GetUVs (/*bool isShadow*/)
+{
+ return hairuvs();
+}
+/*
+| from IHairVoxel
+*/
+int HairVoxel::GetNumVerts () const
+{
+ return hairtype().GetNumVerts();
+}
+/*
+| from IHairVoxel
+*/
+int HairVoxel::GetNumStrands() const
+{
+ return hairtype().GetNumStrands();
+}
+/*
+| from IHairVoxel
+*/
+int HairVoxel::GetNumFaces() const
+{
+ return hairtype().GetNumFaces();
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetVert(int vertidx, float& x, float& y, float& z) const
+{
+ hairtype().GetVert(vertidx,x,y,z);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetVelocity(int vertidx, float& x, float& y, float& z) const
+{
+ hairtype().GetVelocity(vertidx,x,y,z);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetStrand(int strandidx, int& v_start, int& v_end) const
+{
+ hairtype().GetStrand(strandidx,v_start,v_end);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetFace(int faceidx, int& v_start, int& v_end) const
+{
+ hairtype().GetFace(faceidx,v_start,v_end);
+}
+/*
+| from IHairVoxel
+*/
+bool HairVoxel::IsColorConst(int strandidx) const
+{
+ return hairtype().IsColorConst(strandidx);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetRootColor(int strandidx, float& r, float& g, float& b) const
+{
+ hairtype().GetRootColor(strandidx,r,g,b);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetTipColor(int strandidx, float& r, float& g, float& b) const
+{
+ hairtype().GetTipColor(strandidx,r,g,b);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetVertColor(int strandidx, int knot_idx, float& r, float& g, float& b) const
+{
+ hairtype().GetVertColor(strandidx,knot_idx,r,g,b);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetColor(int strandidx, float t, float& r, float& g, float& b) const
+{
+ hairtype().GetColor(strandidx,t,r,g,b);
+}
+/*
+| from IHairVoxel
+*/
+void HairVoxel::GetSurfNormal(int strandidx, float& x, float& y, float& z) const
+{
+ hairtype().GetSurfNormal(strandidx,x,y,z);
+}
+/*
+| from IHairVoxel
+*/
+float HairVoxel::GetStrandGlossiness(int i) const
+{
+ return hairtype().gloss[i];
+}
+/*
+| from IHairVoxel
+*/
+float HairVoxel::GetStrandSpecLevel(int i) const
+{
+ return hairtype().spec[i];
+}
+/*
+| from IHairVoxel
+*/
+float HairVoxel::GetStrandOpacity(int i) const
+{
+ return hairtype().opacity[i];
+}
+/*
+| from IHairVoxel
+*/
+float HairVoxel::GetStrandAmbDiff(int i) const
+{
+ return hairtype().ambdiff[i];
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| HairType wrapper |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+HAIRAPI HairType::HairType(bool init)
+{
+ if(init)
+ {
+ LOGMSG("SHAVE","SHAVE2init_hairtype");
+ SHAVE2init_hairtype(this);
+ }
+ squirrel = false;
+}
+
+HAIRAPI HairType::~HairType()
+{
+ LOGMSG("SHAVE","SHAVE2free_hairtype");
+ SHAVE2free_hairtype(this);
+}
+
+int HairType::GetNumStrands() const
+{
+ return totalfaces;
+}
+
+int HairType::GetNumFaces() const
+{
+ return totalfaces;
+}
+
+int HairType::GetNumVerts() const
+{
+ return totalverts;
+}
+
+int HairType::GetFaceVert(int face_list_idx ) const
+{
+ return facelist[face_list_idx];
+}
+
+void HairType::GetVert(int i, float &x, float &y, float &z) const
+{
+ bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false;
+ if(doswap)
+ {
+ x = v[i].x;
+ y = -v[i].z;
+ z = v[i].y;
+ }
+ else
+ {
+ x = v[i].x;
+ y = v[i].y;
+ z = v[i].z;
+ }
+}
+
+void HairType::GetUV (int i, float& u, float& v, float& w) const
+{
+ u = uvw[i].x;
+ v = uvw[i].y;
+ w = uvw[i].z;
+}
+
+void HairType::GetVelocity(int i, float& x, float& y, float& z) const
+{
+ bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false;
+ if(doswap)
+ {
+ x = velocity[i].x;
+ y = -velocity[i].z;
+ z = velocity[i].y;
+ }
+ else
+ {
+ x = velocity[i].x;
+ y = velocity[i].y;
+ z = velocity[i].z;
+ }
+ //x = 0.0f;
+ //y = 0.0f;
+ //z = 0.0f;
+}
+
+
+void HairType::GetStrand(int i, int& v_start, int& v_end) const
+{
+ v_start = face_start[i];
+ v_end = face_end[i];
+}
+
+void HairType::GetFace(int i, int& v_start, int& v_end) const
+{
+ v_start = face_start[i];
+ v_end = face_end[i];
+}
+
+bool HairType::IsColorConst(int i) const
+{
+ return (colorroot[i].x == colortip[i].x) &&
+ (colorroot[i].y == colortip[i].y) &&
+ (colorroot[i].z == colortip[i].z);
+}
+
+void HairType::GetRootColor(int i, float& r, float& g, float& b) const
+{
+ r = colorroot[i].x;
+ g = colorroot[i].y;
+ b = colorroot[i].z;
+}
+
+void HairType::GetTipColor (int i, float& r, float& g, float& b) const
+{
+ r = colortip[i].x;
+ g = colortip[i].y;
+ b = colortip[i].z;
+}
+
+void HairType::GetVertColor(int i, int v, float& r, float& g, float& b) const
+{
+ if((colorroot[i].x == colortip[i].x) &&
+ (colorroot[i].y == colortip[i].y) &&
+ (colorroot[i].z == colortip[i].z))
+ {
+ r = colorroot[i].x;
+ g = colorroot[i].y;
+ b = colorroot[i].z;
+
+ return;
+ }
+
+ int nknots = face_end[i] - face_start[i];
+ float t = (float)v/(float)nknots;
+ float T = 1.0f - t;
+
+ if (!squirrel)
+ {
+ r = colorroot[i].x*T + colortip[i].x*t;
+ g = colorroot[i].y*T + colortip[i].y*t;
+ b = colorroot[i].z*T + colortip[i].z*t;
+ }
+ else
+ {
+ if (t<.7)
+ {
+ r=colorroot[i].x;
+ g=colorroot[i].y;
+ b=colorroot[i].z;
+ }
+ else
+ {
+ r=colortip[i].x;
+ g=colortip[i].y;
+ b=colortip[i].z;
+ }
+ }
+}
+
+void HairType::GetColor (int i, float t, float& r, float& g, float& b) const
+{
+ if((colorroot[i].x == colortip[i].x) &&
+ (colorroot[i].y == colortip[i].y) &&
+ (colorroot[i].z == colortip[i].z))
+ {
+ r = colorroot[i].x;
+ g = colorroot[i].y;
+ b = colorroot[i].z;
+
+ return;
+ }
+ if (!squirrel)
+ {
+ float T = 1.0f - t;
+ r = colorroot[i].x*T + colortip[i].x*t;
+ g = colorroot[i].y*T + colortip[i].y*t;
+ b = colorroot[i].z*T + colortip[i].z*t;
+ }
+ else
+ {
+ if (t<.7)
+ {
+ r=colorroot[i].x;
+ g=colorroot[i].y;
+ b=colorroot[i].z;
+ }
+ else
+ {
+ r=colortip[i].x;
+ g=colortip[i].y;
+ b=colortip[i].z;
+ }
+ }
+}
+
+void HairType::GetSurfNormal(int i, float& x, float& y, float& z) const
+{
+ bool doswap = owner ? ((HairStack*)owner)->GetNeedYZswap() : false;
+ if(doswap)
+ {
+ x = surfNorm[i].x;
+ y = -surfNorm[i].z;
+ z = surfNorm[i].y;
+ }
+ else
+ {
+ x = surfNorm[i].x;
+ y = surfNorm[i].y;
+ z = surfNorm[i].z;
+ }
+
+}
+
+float HairType::GetStrandGlossiness(int i) const
+{
+ return gloss[i];
+}
+
+float HairType::GetStrandSpecLevel(int i) const
+{
+ return spec[i];
+}
+
+float HairType::GetStrandOpacity(int i) const
+{
+ return opacity[i];
+}
+
+float HairType::GetStrandAmbDiff(int i) const
+{
+ return ambdiff[i];
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
+| HairUVs wrapper |
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+HAIRAPI HairUVs::HairUVs(bool init)
+{
+ if(init)
+ {
+ LOGMSG("SHAVE", "SHAVE2init_UV");
+ SHAVE2init_UV(this);
+ }
+}
+
+HAIRAPI HairUVs::~HairUVs()
+{
+ LOGMSG("SHAVE", "SHAVE2free_UV");
+ //comment for text
+ SHAVE2free_UV(this);
+}
+
+
diff --git a/vrayPlug/plugin/hairAPIimp.h b/vrayPlug/plugin/hairAPIimp.h
new file mode 100644
index 0000000..974673f
--- /dev/null
+++ b/vrayPlug/plugin/hairAPIimp.h
@@ -0,0 +1,333 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: hairAPIImp.h
+
+ DESCRIPTION: Implementation of C++ Intefraces for SHAVE2 functions
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-08-2008
+
+ *>
+ **********************************************************************/
+
+#ifndef _SHAVE2_API_IMPLEMENTATION_H_
+#define _SHAVE2_API_IMPLEMENTATION_H_
+
+#include "hairAPIvrayutil.h"
+#include <vector>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <process.h>
+#else
+#include <pthread.h>
+#endif
+
+#ifndef FLT_MAX
+#define FLT_MAX 3.402823466e+38F
+#endif
+
+#define USE_MEMFILE
+extern "C"
+{
+void SHAVEprint_engine2(void);
+}
+class HairStack;
+
+class HairVoxel : public IHairVoxel {
+public:
+ HAIRAPI HairVoxel();
+
+ HAIRAPI HairVoxel(HairStack* hstack,
+ const VERT& pmin, const VERT& pmai,
+ int ix, int iy, int iz,
+ bool squirrel);
+
+ HAIRAPI HairVoxel(HairStack* hstack,
+ const VERT& pmin, const VERT& pmai,
+ int stack_id, int ix, int iy, int iz,
+ bool squirrel);
+
+ HAIRAPI ~HairVoxel();
+ /*
+ | from IHairVoxel
+ */
+ HAIRAPI bool HasHair() const;
+
+ HAIRAPI bool IsNodeVoxel() const;
+ HAIRAPI int GetNodeID(void) const;
+
+ HAIRAPI bool GetBbox(VERT& pmin, VERT& pmax) const;
+
+ HAIRAPI const HairType& GetHair(/*bool isShadow = false*/);
+ HAIRAPI const HairUVs& GetUVs (/*bool isShadow = false*/);
+
+ /////////////////////////////////////////////////////////////////////////
+ // These methods retrive data from voxel's HairType
+ ////////////////////////////////////////////////////////////////////////
+
+ int GetNumVerts () const;
+ int GetNumStrands() const;
+ int GetNumFaces() const;
+ void GetVert (int vertidx, float& x, float& y, float& z) const;
+ void GetVelocity(int vertidx, float& x, float& y, float& z) const;
+ void GetStrand (int strandidx, int& v_start, int& v_end) const;
+ void GetFace (int faceidx, int& v_start, int& v_end) const;
+ bool IsColorConst (int strandidx) const;
+ void GetRootColor (int strandidx, float& r, float& g, float& b) const;
+ void GetTipColor (int strandidx, float& r, float& g, float& b) const;
+ void GetVertColor (int strandidx, int knot_idx, float& r, float& g, float& b) const;
+ void GetColor (int strandidx, float t, float& r, float& g, float& b) const;
+ void GetSurfNormal(int strandidx, float& x, float& y, float& z) const;
+ float GetStrandGlossiness(int strandidx) const;
+ float GetStrandSpecLevel(int strandidx) const;
+ float GetStrandOpacity(int strandidx) const;
+ float GetStrandAmbDiff(int strandidx) const;
+
+
+protected:
+
+ //const memeber access
+ inline const HairType& hairtype() const {return m_hairtype;}
+ inline const HairUVs& hairuvs() const {return m_hairuvs;}
+ inline HairStack* stack() const {return m_stack;}
+ inline const VERT& bboxMin() const {return m_bboxMin;}
+ inline const VERT& bboxMax() const {return m_bboxMax;}
+ inline bool hashair() const {return m_hashair;}
+ inline bool nodevoxel() const {return m_nodevoxel;}
+ inline int nodeindex() const {return m_nodeindex;}
+ inline bool squirrel() const {return m_squirrel;}
+
+
+ //member access
+ inline HairType& _hairtype(){return m_hairtype;}
+ inline HairUVs& _hairuvs(){return m_hairuvs;}
+ inline HairStack*& _stack() {return m_stack;}
+ inline VERT& _bboxMin() {return m_bboxMin;}
+ inline VERT& _bboxMax() {return m_bboxMax;}
+ inline bool& _hashair() {return m_hashair;}
+ inline bool& _nodevoxel() {return m_nodevoxel;}
+ inline int& _nodeindex() {return m_nodeindex;}
+ inline bool& _squirrel() {return m_squirrel;}
+
+private:
+ bool m_hashair;
+ bool m_nodevoxel;
+ int m_nodeindex;
+ HairType m_hairtype;
+ HairUVs m_hairuvs;
+ VERT m_bboxMin;
+ VERT m_bboxMax;
+ HairStack* m_stack;
+ bool m_squirrel;
+};
+
+#ifndef _VOXEL_VECTOR_TYPE_
+#define _VOXEL_VECTOR_TYPE_
+typedef std::vector<HairVoxel*> HVoxels;
+#endif
+
+#ifndef _INT_VECTOR_TYPE_
+#define _INT_VECTOR_TYPE_
+typedef std::vector<int> intvector;
+#endif
+
+
+class HairNode : public IHairNode {
+public:
+ HAIRAPI HairNode(HairStack* hstack, int stack_id, bool squirrel);
+ HAIRAPI ~HairNode();
+
+ /*
+ | from IHairNode
+ */
+ HAIRAPI bool GetBbox(VERT& pmin, VERT& pmax) const;
+ HAIRAPI int GetStackID() const;
+ HAIRAPI int GetNumVoxels()const;
+ HAIRAPI IHairVoxel* GetVoxel(int i) const;
+
+ /////////////////////////////////////////////////////////////////////////
+ // These methods retrieve data from node's voxels
+ ////////////////////////////////////////////////////////////////////////
+
+ int GetNumVerts () const;
+ int GetNumStrands() const;
+ int GetNumFaces() const;
+ void GetVert (int vertidx, float& x, float& y, float& z) const;
+ void GetVelocity(int vertidx, float& x, float& y, float& z) const;
+ void GetStrand (int strandidx, int& v_start, int& v_end) const;
+ void GetFace (int faceidx, int& v_start, int& v_end) const;
+ bool IsColorConst (int strandidx) const;
+ void GetRootColor (int strandidx, float& r, float& g, float& b) const;
+ void GetTipColor (int strandidx, float& r, float& g, float& b) const;
+ void GetVertColor (int strandidx, int knot_idx, float& r, float& g, float& b) const;
+ void GetColor (int strandidx, float t, float& r, float& g, float& b) const;
+ void GetSurfNormal(int strandidx, float& x, float& y, float& z) const;
+ float GetStrandGlossiness(int strandidx) const;
+ float GetStrandSpecLevel(int strandidx) const;
+ float GetStrandOpacity(int strandidx) const;
+ float GetStrandAmbDiff(int strandidx) const;
+
+protected:
+ inline bool vertIndexToVoxVertIndex(int i, int& vox, int& vox_vert) const
+ {
+ if(i < (int)vtovoxs().size())
+ {
+ vox = vtovox(i);
+ vox_vert = vtovoxV(i);
+ return true;
+ }
+ return false;
+ }
+ inline bool strandIndexToVoxStrandIndex(int i, int& vox, int& vox_strand) const
+ {
+ if(i < (int)stovoxs().size())
+ {
+ vox = stovox(i);
+ vox_strand = stovoxS(i);
+ return true;
+ }
+ return false;
+ }
+ //const member access
+ inline int stackid() const {return m_stackid;}
+ inline const HVoxels& voxels() const {return m_voxels;}
+ inline HairVoxel* voxel(int i) const {return m_voxels[i];}
+ inline HairStack* stack() const {return m_stack;}
+ inline const VERT& bboxMin() const {return m_bboxMin;}
+ inline const VERT& bboxMax() const {return m_bboxMax;}
+ inline const intvector& vtovoxs() const {return m_vtovoxs;}
+ inline int vtovox(int i) const {return m_vtovoxs[i];}
+ inline const intvector& vtovoxVs() const {return m_vtovoxVs;}
+ inline int vtovoxV(int i)const {return m_vtovoxVs[i];}
+ inline const intvector& stovoxs() const {return m_stovoxs;}
+ inline int stovox(int i) const {return m_stovoxs[i];}
+ inline const intvector& stovoxSs() const {return m_stovoxSs;}
+ inline int stovoxS(int i)const {return m_stovoxSs[i];}
+ inline bool squirrel() const {return m_squirrel;}
+
+ //member access
+ inline int& _stackid() {return m_stackid;}
+ inline HVoxels& _voxels() {return m_voxels;}
+ inline HairVoxel*& _voxel(int i) {return m_voxels[i];}
+ inline HairStack*& _stack() {return m_stack;}
+ inline VERT& _bboxMin() {return m_bboxMin;}
+ inline VERT& _bboxMax() {return m_bboxMax;}
+ inline intvector& _vtovoxs() {return m_vtovoxs;}
+ inline int& _vtovox(int i) {return m_vtovoxs[i];}
+ inline intvector& _vtovoxVs() {return m_vtovoxVs;}
+ inline int& _vtovoxV(int i){return m_vtovoxVs[i];}
+ inline intvector& _stovoxs() {return m_stovoxs;}
+ inline int& _stovox(int i) {return m_stovoxs[i];}
+ inline intvector& _stovoxSs() {return m_stovoxSs;}
+ inline int& _stovoxV(int i){return m_stovoxSs[i];}
+ inline bool& _squirrel() {return m_squirrel;}
+
+
+private:
+ int m_stackid;
+ HVoxels m_voxels;
+ HairStack* m_stack;
+ VERT m_bboxMin;
+ VERT m_bboxMax;
+ intvector m_vtovoxs; //maps vert index to voxel index
+ intvector m_vtovoxVs; //maps vert index to vert index of voxel
+ intvector m_stovoxs; //maps strand index to voxel index
+ intvector m_stovoxSs; //maps strand index to strand index of voxel
+ bool m_squirrel;
+};
+
+
+#ifndef _NODE_VECTOR_TYPE_
+#define _NODE_VECTOR_TYPE_
+typedef std::vector<HairNode*> HNodes;
+#endif
+
+
+class HairStack : public IHairStack {
+public:
+ HAIRAPI HairStack(void* bdata, long size, bool needxyswap);
+ HAIRAPI HairStack(char* fname, bool needxyswap);
+ HAIRAPI ~HairStack();
+
+ /*
+ | from IHairStack
+ */
+ HAIRAPI bool Init(void* bdata, long size);
+ HAIRAPI bool Init(char* fname);
+
+ HAIRAPI void Clear();
+
+ HAIRAPI char* GetDRAname() const;
+
+ HAIRAPI int GetNumVoxels() const;
+ HAIRAPI int GetVoxelRes() const;
+
+ HAIRAPI IHairVoxel* GetHairVoxel(int vox_x, int vox_y, int vox_z);
+ HAIRAPI IHairVoxel* GetHairVoxel(int vox_index);
+
+ HAIRAPI IHairNode* GetHairNodeByID (int stack_id, bool squirrel = false);
+
+ HAIRAPI bool GetNeedYZswap() const {return needyzswap();}
+#ifdef USE_MEMFILE
+ MEMFILE* GetMemFile() { return &_mem();}
+#endif
+ void Lock();
+ void UnLock();
+
+protected:
+#ifdef WIN32
+ CRITICAL_SECTION csect;
+#else
+ pthread_mutex_t mutex;
+#endif
+ inline bool voxelXYZformIDX(int index, int& x, int& y, int& z);
+ inline bool voxelIDXformXYZ(int& index, int x, int y, int z);
+
+ //const member access
+ inline char* draname() const {return m_draname;}
+ inline const HNodes& nodes() const {return m_nodes;}
+ inline HairNode* node(int i) const {return m_nodes[i];}
+ inline const HVoxels& voxels() const {return m_voxels;}
+ inline HairVoxel* voxel(int i)const {return m_voxels[i];}
+ inline int voxres() const {return m_voxres;}
+ inline bool needyzswap()const {return m_needyzswap;}
+#ifdef USE_MEMFILE
+ inline const MEMFILE& mem() const {return m_mem;}
+#endif
+
+ //member access
+ inline char*& _draname() {return m_draname;}
+ inline HNodes& _nodes() {return m_nodes;}
+ inline HairNode*& _node(int i) {return m_nodes[i];}
+ inline HVoxels& _voxels() {return m_voxels;}
+ inline HairVoxel*& _voxel(int i){return m_voxels[i];}
+ inline int& _voxres() {return m_voxres;}
+ inline bool& _needyzswap(){return m_needyzswap;}
+#ifdef USE_MEMFILE
+ inline MEMFILE& _mem() {return m_mem;}
+#endif
+
+
+private:
+ char* m_draname;
+ HNodes m_nodes;
+ HVoxels m_voxels;
+ int m_voxres;
+ bool m_needyzswap;
+#ifdef USE_MEMFILE
+ MEMFILE m_mem;
+#endif
+};
+
+
+
+
+
+#endif //end of _SHAVE2_API_IMPLEMENTATION_H_
+
diff --git a/vrayPlug/plugin/hairAPIvray.h b/vrayPlug/plugin/hairAPIvray.h
new file mode 100644
index 0000000..aeed420
--- /dev/null
+++ b/vrayPlug/plugin/hairAPIvray.h
@@ -0,0 +1,86 @@
+#ifndef _HAIR_API_VRAY_H_
+#define _HAIR_API_VRAY_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "rayserver.h"
+#include "geometryclasses.h"
+#include "brdfs.h"
+#include "brdfpool.h"
+#include "vray3_compat.h"
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the SHAVEVRAYSH_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// SHAVEVRAYSH_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef WIN32
+#ifdef SHAVEVRAYSH_EXPORTS
+#define SHAVEVRAYSH_API __declspec(dllexport)
+#else
+#define SHAVEVRAYSH_API __declspec(dllimport)
+#endif
+#else
+#define SHAVEVRAYSH_API
+#endif
+
+// Define APIENTRY per platform
+#ifndef APIENTRY
+# define APIENTRY
+#endif
+
+class IShaveVrayBSDF : public VR::BRDFSampler,
+ public VR::BSDFSampler{
+public:
+ // Initialization
+ virtual void init(
+ const VR::VRayContext &rc,
+ const VR::Color &reflectionColor,
+ const VR::Color &diffuseColor,
+ const VR::Color &ambientColor,
+ const VR::Color &specularTint,
+ const VR::Color &specularTint2,
+ float ambDiff,
+ float specularLevel,
+ float reflectionGlossiness,
+ int subdivs, const VR::Color &transp,
+ const VR::ShadeVec &hairDir,
+ float requiredTransparency,
+ bool cameraVisibility,
+ bool reflVisibility,
+ bool refrVisibility,
+ bool lightVisibility,
+ bool giVisibility,
+ float selfShadowing,
+ bool recvShadow) = 0;
+};
+
+class IShaveBSDFPool {
+public:
+ virtual void init(VR::VRayCore *vray) = 0;
+ virtual void freeMem() = 0;
+
+ virtual IShaveVrayBSDF* newBRDF(const VR::VRayContext &rc) = 0;
+ virtual void deleteBRDF(const VR::VRayContext &rc, IShaveVrayBSDF* bsdf) = 0;
+};
+
+#ifdef LINUX
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+typedef IShaveBSDFPool* (APIENTRY * PFNCREATEBSDFPOOL)();
+#ifdef LINUX
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif //end of _HAIR_API_VRAY_H_
diff --git a/vrayPlug/plugin/hairAPIvrayutil.h b/vrayPlug/plugin/hairAPIvrayutil.h
new file mode 100644
index 0000000..72f7dff
--- /dev/null
+++ b/vrayPlug/plugin/hairAPIvrayutil.h
@@ -0,0 +1,90 @@
+#ifndef HAIR_API_VRAY_UTIL_H
+#define HAIR_API_VRAY_UTIL_H
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "vray3_compat.h"
+#include "hairAPI.h"
+
+// Utility methods to get a Vector/ShadeVec/Color/ShadeCol from the Hair types
+#define DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, TResult)\
+ static void Get##Thing(const Type& obj, TArg1 arg1, TResult &result) {\
+ float x, y, z;\
+ obj.Get##Thing(arg1, x, y, z);\
+ result.set(x, y, z);\
+ }\
+ static void Get##Thing(const Type *obj, TArg1 arg1, TResult &result) {\
+ vassert(obj);\
+ Get##Thing(*obj, arg1, result);\
+ }
+
+#define DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, TResult)\
+ static void Get##Thing(const Type& obj, TArg1 arg1, TArg2 arg2, TResult &result) {\
+ float x, y, z;\
+ obj.Get##Thing(arg1, arg2, x, y, z);\
+ result.set(x, y, z);\
+ }\
+ static void Get##Thing(const Type *obj, TArg1 arg1, TArg2 arg2, TResult &result) {\
+ vassert(obj);\
+ Get##Thing(*obj, arg1, arg2, result);\
+ }
+
+#if defined(VRAY30)
+#define DECLARE_GETTER1_Vector(Type, Thing, TArg1)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::Vector)
+
+#define DECLARE_GETTER2_Vector(Type, Thing, TArg1, TArg2)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::Vector)
+
+#define DECLARE_GETTER1_Color(Type, Thing, TArg1)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::Color)
+
+#define DECLARE_GETTER2_Color(Type, Thing, TArg1, TArg2)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::Color)
+
+#elif defined(VRAY40)
+#define DECLARE_GETTER1_Vector(Type, Thing, TArg1)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::Vector)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::simd::Vector3f)
+
+#define DECLARE_GETTER2_Vector(Type, Thing, TArg1, TArg2)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::Vector)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::simd::Vector3f)
+
+#define DECLARE_GETTER1_Color(Type, Thing, TArg1)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::Color)\
+ DECLARE_GETTER1_TRESULT(Type, Thing, TArg1, VUtils::simd::Color3f)
+
+#define DECLARE_GETTER2_Color(Type, Thing, TArg1, TArg2)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::Color)\
+ DECLARE_GETTER2_TRESULT(Type, Thing, TArg1, TArg2, VUtils::simd::Color3f)
+
+#endif
+
+DECLARE_GETTER1_Vector(IHairVoxel, Vert, int)
+DECLARE_GETTER1_Vector(IHairVoxel, Velocity, int)
+DECLARE_GETTER1_Color(IHairVoxel, RootColor, int)
+DECLARE_GETTER1_Color(IHairVoxel, TipColor, int)
+DECLARE_GETTER2_Color(IHairVoxel, VertColor, int, int)
+DECLARE_GETTER2_Color(IHairVoxel, Color, int, float)
+DECLARE_GETTER1_Vector(IHairVoxel, SurfNormal, int)
+
+DECLARE_GETTER1_Vector(HairType, Vert, int)
+DECLARE_GETTER1_Vector(HairType, UV, int)
+DECLARE_GETTER1_Vector(HairType, Velocity, int)
+DECLARE_GETTER1_Color(HairType, RootColor, int)
+DECLARE_GETTER1_Color(HairType, TipColor, int)
+DECLARE_GETTER2_Color(HairType, VertColor, int, int)
+DECLARE_GETTER2_Color(HairType, Color, int, float)
+DECLARE_GETTER1_Vector(HairType, SurfNormal, int)
+
+#undef DECLARE_GETTER1_TRESULT
+#undef DECLARE_GETTER2_TRESULT
+#undef DECLARE_GETTER1_Vector
+#undef DECLARE_GETTER2_Vector
+#undef DECLARE_GETTER1_Color
+#undef DECLARE_GETTER2_Color
+#endif //HAIR_API_VRAY_UTIL_H
+
diff --git a/vrayPlug/plugin/osxMavericks_x64_vray36.mak b/vrayPlug/plugin/osxMavericks_x64_vray36.mak
new file mode 100644
index 0000000..d8eac01
--- /dev/null
+++ b/vrayPlug/plugin/osxMavericks_x64_vray36.mak
@@ -0,0 +1,173 @@
+include ../../config-osx.mak
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+OUTDIR = ../bin/mavericks
+TMPDIR = ./build/release/mavericks/vray36
+
+
+OBJS = \
+$(TMPDIR)/shaveSDKCALLBACKS.obj \
+$(TMPDIR)/hairAPIimp.obj \
+$(TMPDIR)/pluginMain.obj \
+$(TMPDIR)/shaveVrayBaseBSDF.obj \
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj \
+$(TMPDIR)/shaveVrayDesc.obj \
+$(TMPDIR)/shaveVrayInstance.obj \
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj \
+$(TMPDIR)/shaveVrayPlugin.obj \
+$(TMPDIR)/shaveVrayShadeable.obj \
+$(TMPDIR)/shaveVrayShadeData.obj \
+$(TMPDIR)/shaveVraySharedFunctions.obj \
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj \
+$(TMPDIR)/shaveVrayVoxelPrim.obj \
+$(TMPDIR)/shaveVrayInstanceBase.obj \
+$(TMPDIR)/shaveVrayInstanceI.obj \
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayTriShadeable.obj \
+$(TMPDIR)/shaveVrayTriShadeData.obj
+
+# We do NOT want to specify MINVER as that has already been determined by
+# the caller setting MACOSX_DEPLOYMENT_TARGET and we don't want to override
+# that.
+#
+MINVER =
+
+ARCH = -arch x86_64
+
+FWORKS = -framework System \
+ -framework CoreServices \
+ -framework Carbon \
+ -framework Cocoa \
+ -framework ApplicationServices \
+ -framework IOKit
+
+GCCFLAGS = -msse -msse2 $(sdkLibFlag) \
+ $(ARCH) -DBits64_ -fvisibility=hidden -headerpad_max_install_names \
+ $(FWORKS) $(MINVER) -dynamic -bundle -flat_namespace
+
+GCCFLAGS_OBJ = --prefix=/usr -O2 -fvisibility=hidden -ffunction-sections -fdata-sections -finline-functions -funswitch-loops $(sdkRootFlag) \
+ -ffast-math -msse -msse2 $(ARCH) -DBits64_ \
+ -D_LANGUAGE_C_PLUS_PLUS -DREQUIRE_IOSTREAM \
+ -DHAVE_EXR -D_REENTRANT $(MINVER) -fexceptions -D "NDEBUG" -D "VRAY30" -D VRAY_EXPORTS
+
+G++FLAGS_OBJ = $(GCCFLAGS_OBJ) -Wno-c++11-extensions -Wno-nonnull
+
+SHAVELIB = "../../libexe/shaveLibAW2-x86_64.a"
+
+#
+# std libs
+#
+LIBS = -lpthread -lc -lz -ldl -lplugman_s -lvutils_s -lrayserver_s -lvray $(SHAVELIB)
+LIBDIRS = -L. -L"$(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/osx"
+INCDIRS = -I. -I"$(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include" -I"../../libexe/sample/include"
+
+all: $(OUTDIR)/libvray_Shave36.so
+
+$(OUTDIR)/libvray_Shave36.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(LIBDIRS) $(LIBS) -o "$(OUTDIR)/libvray_Shave36.so" -O $(OBJS)
+ strip -X "$(OUTDIR)/libvray_Shave36.so"
+
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+$(TMPDIR)/shaveSDKCALLBACKS.obj: shaveSDKCALLBACKS.c
+ $(CC) $(GCCFLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveSDKCALLBACKS.obj" "shaveSDKCALLBACKS.c"
+
+
+$(TMPDIR)/hairAPIimp.obj: hairAPIimp.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/hairAPIimp.obj" "hairAPIimp.cpp"
+
+
+$(TMPDIR)/pluginMain.obj: pluginMain.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/pluginMain.obj" "pluginMain.cpp"
+
+
+$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+
+
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj: shaveVrayBaseBSDFPool.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayBaseBSDFPool.obj" "shaveVrayBaseBSDFPool.cpp"
+
+
+$(TMPDIR)/shaveVrayDesc.obj: shaveVrayDesc.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayDesc.obj" "shaveVrayDesc.cpp"
+
+
+$(TMPDIR)/shaveVrayInstance.obj: shaveVrayInstance.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstance.obj" "shaveVrayInstance.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj: shaveVrayMovingVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayMovingVoxelPrim.obj" "shaveVrayMovingVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayPlugin.obj: shaveVrayPlugin.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayPlugin.obj" "shaveVrayPlugin.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeable.obj: shaveVrayShadeable.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayShadeable.obj" "shaveVrayShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeData.obj: shaveVrayShadeData.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayShadeData.obj" "shaveVrayShadeData.cpp"
+
+
+$(TMPDIR)/shaveVraySharedFunctions.obj: shaveVraySharedFunctions.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVraySharedFunctions.obj" "shaveVraySharedFunctions.cpp"
+
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj: shaveVrayStaticVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayStaticVoxelPrim.obj" "shaveVrayStaticVoxelPrim.cpp"
+
+$(TMPDIR)/shaveVrayVoxelPrim.obj: shaveVrayVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayVoxelPrim.obj" "shaveVrayVoxelPrim.cpp"
+
+#instanced hair
+
+
+$(TMPDIR)/shaveVrayInstanceBase.obj: shaveVrayInstanceBase.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstanceBase.obj" "shaveVrayInstanceBase.cpp"
+
+
+$(TMPDIR)/shaveVrayInstanceI.obj: shaveVrayInstanceI.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstanceI.obj" "shaveVrayInstanceI.cpp"
+
+
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj: shaveVrayTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriVoxelPrim.obj" "shaveVrayTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj: shaveVrayMovingTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj" "shaveVrayMovingTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj: shaveVrayStaticTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj" "shaveVrayStaticTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeable.obj: shaveVrayTriShadeable.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriShadeable.obj" "shaveVrayTriShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeData.obj: shaveVrayTriShadeData.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriShadeData.obj" "shaveVrayTriShadeData.cpp"
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/libvray_Shave36.so
+
diff --git a/vrayPlug/plugin/osxMavericks_x64_vray40.mak b/vrayPlug/plugin/osxMavericks_x64_vray40.mak
new file mode 100644
index 0000000..dcb9e88
--- /dev/null
+++ b/vrayPlug/plugin/osxMavericks_x64_vray40.mak
@@ -0,0 +1,173 @@
+include ../../config-osx.mak
+
+ifndef SHAVE_VRAY_SDKS
+$(error "SHAVE_VRAY_SDKS is not defined.")
+endif
+
+ifndef VRAY_VERSION
+$(error "VRAY_VERSION is not defined.")
+endif
+
+OUTDIR = ../bin/mavericks
+TMPDIR = ./build/release/mavericks/vray40
+
+
+OBJS = \
+$(TMPDIR)/shaveSDKCALLBACKS.obj \
+$(TMPDIR)/hairAPIimp.obj \
+$(TMPDIR)/pluginMain.obj \
+$(TMPDIR)/shaveVrayBaseBSDF.obj \
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj \
+$(TMPDIR)/shaveVrayDesc.obj \
+$(TMPDIR)/shaveVrayInstance.obj \
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj \
+$(TMPDIR)/shaveVrayPlugin.obj \
+$(TMPDIR)/shaveVrayShadeable.obj \
+$(TMPDIR)/shaveVrayShadeData.obj \
+$(TMPDIR)/shaveVraySharedFunctions.obj \
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj \
+$(TMPDIR)/shaveVrayVoxelPrim.obj \
+$(TMPDIR)/shaveVrayInstanceBase.obj \
+$(TMPDIR)/shaveVrayInstanceI.obj \
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj \
+$(TMPDIR)/shaveVrayTriShadeable.obj \
+$(TMPDIR)/shaveVrayTriShadeData.obj
+
+
+# We do NOT want to specify MINVER as that has already been determined by
+# the caller setting MACOSX_DEPLOYMENT_TARGET and we don't want to override
+# that.
+#
+MINVER =
+
+ARCH = -arch x86_64
+
+FWORKS = -framework System \
+ -framework CoreServices \
+ -framework Carbon \
+ -framework Cocoa \
+ -framework ApplicationServices \
+ -framework IOKit
+
+GCCFLAGS = -msse -msse2 $(sdkLibFlag) \
+ $(ARCH) -DBits64_ -fvisibility=hidden -headerpad_max_install_names \
+ $(FWORKS) $(MINVER) -dynamic -bundle -flat_namespace
+
+GCCFLAGS_OBJ = --prefix=/usr -O2 -fvisibility=hidden -ffunction-sections -fdata-sections -finline-functions -funswitch-loops $(sdkRootFlag) \
+ -ffast-math -msse -msse2 $(ARCH) -DBits64_ \
+ -D_LANGUAGE_C_PLUS_PLUS -DREQUIRE_IOSTREAM \
+ -DHAVE_EXR -D_REENTRANT $(MINVER) -fexceptions -D "NDEBUG" -D "VRAY40" -D VRAY_EXPORTS
+G++FLAGS_OBJ = $(GCCFLAGS_OBJ) -std=c++11
+
+SHAVELIB = "../../libexe/shaveLibAW2-x86_64.a"
+
+#
+# std libs
+#
+LIBS = -lpthread -lc -lz -ldl -lplugman_s -lvutils_s -lrayserver_s -lvray $(SHAVELIB)
+LIBDIRS = -L. -L"$(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/lib/osx"
+INCDIRS = -I. -I"$(SHAVE_VRAY_SDKS)/$(VRAY_VERSION)/include" -I"../../libexe/sample/include"
+
+all: $(OUTDIR)/libvray_Shave40.so
+
+$(OUTDIR)/libvray_Shave40.so: $(TMPDIR) $(OUTDIR) $(OBJS)
+ $(C++) $(GCCFLAGS) $(LIBDIRS) $(LIBS) -o "$(OUTDIR)/libvray_Shave40.so" -O $(OBJS)
+ strip -X "$(OUTDIR)/libvray_Shave40.so"
+
+
+$(TMPDIR):
+ -@mkdir -p "$(TMPDIR)"
+
+$(OUTDIR):
+ -@mkdir -p "$(OUTDIR)"
+
+$(TMPDIR)/shaveSDKCALLBACKS.obj: shaveSDKCALLBACKS.c
+ $(CC) $(GCCFLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveSDKCALLBACKS.obj" "shaveSDKCALLBACKS.c"
+
+
+$(TMPDIR)/hairAPIimp.obj: hairAPIimp.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/hairAPIimp.obj" "hairAPIimp.cpp"
+
+
+$(TMPDIR)/pluginMain.obj: pluginMain.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/pluginMain.obj" "pluginMain.cpp"
+
+
+$(TMPDIR)/shaveVrayBaseBSDF.obj: shaveVrayBaseBSDF.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayBaseBSDF.obj" "shaveVrayBaseBSDF.cpp"
+
+
+
+$(TMPDIR)/shaveVrayBaseBSDFPool.obj: shaveVrayBaseBSDFPool.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayBaseBSDFPool.obj" "shaveVrayBaseBSDFPool.cpp"
+
+
+$(TMPDIR)/shaveVrayDesc.obj: shaveVrayDesc.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayDesc.obj" "shaveVrayDesc.cpp"
+
+
+$(TMPDIR)/shaveVrayInstance.obj: shaveVrayInstance.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstance.obj" "shaveVrayInstance.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingVoxelPrim.obj: shaveVrayMovingVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayMovingVoxelPrim.obj" "shaveVrayMovingVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayPlugin.obj: shaveVrayPlugin.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayPlugin.obj" "shaveVrayPlugin.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeable.obj: shaveVrayShadeable.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayShadeable.obj" "shaveVrayShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayShadeData.obj: shaveVrayShadeData.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayShadeData.obj" "shaveVrayShadeData.cpp"
+
+
+$(TMPDIR)/shaveVraySharedFunctions.obj: shaveVraySharedFunctions.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVraySharedFunctions.obj" "shaveVraySharedFunctions.cpp"
+
+$(TMPDIR)/shaveVrayStaticVoxelPrim.obj: shaveVrayStaticVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayStaticVoxelPrim.obj" "shaveVrayStaticVoxelPrim.cpp"
+
+$(TMPDIR)/shaveVrayVoxelPrim.obj: shaveVrayVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayVoxelPrim.obj" "shaveVrayVoxelPrim.cpp"
+
+#instanced hair
+
+
+$(TMPDIR)/shaveVrayInstanceBase.obj: shaveVrayInstanceBase.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstanceBase.obj" "shaveVrayInstanceBase.cpp"
+
+
+$(TMPDIR)/shaveVrayInstanceI.obj: shaveVrayInstanceI.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayInstanceI.obj" "shaveVrayInstanceI.cpp"
+
+
+$(TMPDIR)/shaveVrayTriVoxelPrim.obj: shaveVrayTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriVoxelPrim.obj" "shaveVrayTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj: shaveVrayMovingTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayMovingTriVoxelPrim.obj" "shaveVrayMovingTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj: shaveVrayStaticTriVoxelPrim.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayStaticTriVoxelPrim.obj" "shaveVrayStaticTriVoxelPrim.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeable.obj: shaveVrayTriShadeable.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriShadeable.obj" "shaveVrayTriShadeable.cpp"
+
+
+$(TMPDIR)/shaveVrayTriShadeData.obj: shaveVrayTriShadeData.cpp
+ $(C++) $(G++FLAGS_OBJ) $(INCDIRS) -c -o "$(TMPDIR)/shaveVrayTriShadeData.obj" "shaveVrayTriShadeData.cpp"
+
+clean:
+ -@rm -f $(TMPDIR)/*.obj
+ -@rm -f $(OUTDIR)/libvray_Shave40.so
+
diff --git a/vrayPlug/plugin/pluginMain.cpp b/vrayPlug/plugin/pluginMain.cpp
new file mode 100644
index 0000000..f225ae3
--- /dev/null
+++ b/vrayPlug/plugin/pluginMain.cpp
@@ -0,0 +1,259 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "shaveVrayPlugin.h"
+#include "shaveVrayDesc.h"
+#include "shaveVraySharedFunctions.h"
+
+extern "C"
+{
+#include "shaveSDKFUNCS2.h"
+}
+
+using namespace VR;
+
+// defined in shaveVrayPlugin.cpp; set to true if SHAVE2init() has been called.
+extern int shaveInitCalled;
+
+struct shaveVrayParams: public VR::VRayParameterListDesc {
+public:
+ shaveVrayParams() {
+ // Cannot initialise here because this struct is initialised
+ // when the plugin is loaded before the check for V-Ray's
+ // version runs and the addParamX methods of V-Ray 3 and 4
+ // differ. This leads to a crash on MacOS. On other OSes the
+ // dll simply doesn't load.
+ }
+ void init();
+ virtual ~shaveVrayParams(){}
+};
+
+
+void shaveVrayParams::init()
+{
+ addParamInt (VR30_CONST_STR_HACK("stackId"), 0, -1);
+ addParamInt (VR30_CONST_STR_HACK("instanced"),0, -1);
+ addParamInt (VR30_CONST_STR_HACK("ownshader"),1, -1);
+ addParamInt (VR30_CONST_STR_HACK("squirrel"),0, -1);
+ addParamInt (VR30_CONST_STR_HACK("tipfade"),0, -1);
+ addParamColor (VR30_CONST_STR_HACK("spectint"), VR::Color(1.0f,1.0f,1.0f), -1);
+ addParamColor (VR30_CONST_STR_HACK("spectint2"),VR::Color(0.0f,0.0f,0.0f), -1);
+ addParamString(VR30_CONST_STR_HACK("draFile"), "",-1);
+ addParamString(VR30_CONST_STR_HACK("libPath"), "",-1);
+
+ //uvs relaated params
+ //DefVectorListParam is used for uvs list
+ addParamInt(VR30_CONST_STR_HACK("numFacesPerInst"),0,-1);
+ addParamInt(VR30_CONST_STR_HACK("numUVSets"),0,-1);
+ //If -1, then this is not a list parameter;
+ //if 0 then this is a list parameter of unspecified (arbitrary) length.
+ //If this is >0, then it is the number of required elements in the parameter.
+ addParamVector(VR30_CONST_STR_HACK("uvs"),VR::Vector(),0);
+
+ addParamInt(VR30_CONST_STR_HACK("draData"),0,0);
+ addParamInt(VR30_CONST_STR_HACK("draSize"),0,-1);
+
+ //visibility related params
+ addParamInt(VR30_CONST_STR_HACK("cameraVisibility"),1, -1);
+ addParamInt(VR30_CONST_STR_HACK("reflVisibility"),1, -1);
+ addParamInt(VR30_CONST_STR_HACK("refrVisibility"),1, -1);
+ addParamInt(VR30_CONST_STR_HACK("lightVisibility"),1, -1);
+ addParamInt(VR30_CONST_STR_HACK("GiVisibility"),1, -1);
+
+ addParamFloat(VR30_CONST_STR_HACK("selfShadow"),1.0f, -1);
+ addParamInt(VR30_CONST_STR_HACK("recvShadow"),1, -1);
+#if defined(VRAY30) || defined(VRAY40)
+ addParamInt(VR30_CONST_STR_HACK("useGlobalHairTree"),1 /*1*/, -1);
+ addParamInt(VR30_CONST_STR_HACK("dynamicHairTesselation"),0, -1);
+ addParamFloat(VR30_CONST_STR_HACK("hairTesselMaxEdgleLen"),4.0f, -1);
+#endif
+}
+
+#if defined(VRAY40)
+# define BUILT_FOR "4.0"
+#elif defined(VRAY30)
+# if VRAY_DLL_VERSION < 0x31000
+# define BUILT_FOR "3.0"
+# elif VRAY_DLL_VERSION < 0x36000
+# define BUILT_FOR "3.1"
+# else
+# define BUILT_FOR "3.6"
+# endif
+#else
+# define BUILT_FOR "2.0"
+#endif
+
+// We don't use the PLUGIN_DESC macro as we need to call the Shave cleanup function
+// when the plugin is unloaded.
+class shaveVrayPluginDesc: public VRayPluginDesc {
+ int attachCount;
+ VUtils::FastCriticalSection attachCsect;
+public:
+ shaveVrayParams shaveVrayPlugin_params;
+ shaveVrayPluginDesc(void):VRayPluginDesc(NULL), attachCount(0) {
+ parameters=&shaveVrayPlugin_params;
+ (*getNumDescs())++;
+ DescList *nd=new DescList;
+ nd->desc=this;
+ nd->next=(*getFirstDesc());
+ (*getFirstDesc())=nd;
+
+ unsigned int vr_rev = VR::getVRayRevision();
+
+ unsigned int vr_rev_max;
+ unsigned int vr_rev_min;
+#if defined(VRAY40)
+ vr_rev_min = 0x40000;
+ vr_rev_max = 0x50000;
+#elif defined(VRAY30)
+# if VRAY_DLL_VERSION < 0x31000
+ vr_rev_min = 0x30000;
+ vr_rev_max = 0x31000;
+# elif VRAY_DLL_VERSION < 0x36000
+ vr_rev_min = 0x31000;
+ vr_rev_max = 0x36000;
+# else
+ vr_rev_min = 0x31000;
+ vr_rev_max = 0x40000;
+# endif
+#else
+ vr_rev_min = 0;
+ vr_rev_max = 0x30000;
+#endif
+ if (vr_rev < vr_rev_min || vr_rev >= vr_rev_max) {
+ (*getNumDescs())=0;
+ (*getFirstDesc())=NULL;
+ printf("Skipping shave shaders for V-Ray " BUILT_FOR ".\n");fflush(stdout);
+ } else {
+ shaveVrayPlugin_params.init();
+ printf("Loaded shave shaders for V-Ray " BUILT_FOR ".\n");fflush(stdout);
+ }
+ }
+ PluginID getPluginID(void) { return shaveVrayPluginID; }
+ Plugin* newPlugin(PluginHost *host) { return new shaveVrayPlugin(this); }
+ void deletePlugin(Plugin *obj) { delete (shaveVrayPlugin*) obj; }
+ bool supportsInterface(InterfaceID id) { return (id==EXT_STATIC_GEOM_SOURCE) || (id==EXT_VRAY_PLUGIN); }
+#ifdef VRAY40
+ const tchar *getName(void) { return shaveVrayPluginName; }
+ const tchar *getDescription() const { return "Shave and a Haircut support for V-Ray"; }
+#else
+ tchar *getName(void) { return const_cast<tchar*>(shaveVrayPluginName); }
+#endif
+ const tchar *getCopyright(void) { return "(c) 2019 Epic Games"; }
+
+ void attachToHost(PluginHost *host) {
+ VUtils::FastCriticalSectionRAII lock(attachCsect);
+ attachCount++;
+ }
+
+ void detachFromHost(PluginHost *host) {
+ VRayPluginDesc::detachFromHost(host);
+
+ VUtils::FastCriticalSectionRAII lock(attachCsect);
+ attachCount--;
+ // Call Shave cleanup, but only if it has been initialized for some render before.
+ if (shaveInitCalled && attachCount==0) {
+ SHAVE2cleanup();
+ shaveInitCalled=false;
+ }
+ }
+};
+
+static shaveVrayPluginDesc desc_shaveVrayPlugin;
+
+// PLUGIN_DESC(shaveVrayPluginID, EXT_STATIC_GEOM_SOURCE, shaveVrayPluginName, shaveVrayPlugin, shaveVrayParams);
+
+PLUGIN_LIBRARY(VR30_CONST_STR_HACK("shavePlugins"), VR30_CONST_STR_HACK("shaveVrayShader plug-in."));
+
+#ifdef WIN32
+#ifdef _MANAGED
+#pragma managed(push, off)
+#endif
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ hInstance = hModule;
+
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+#if 0 // this is handled in the PluginDesc constructor now
+ unsigned int vr_rev = VR::getVRayRevision();
+ //printf("vray version 0x%x \n", vr_rev);fflush(stdout);
+#ifdef VRAY30
+ if(vr_rev < 0x30000)
+ {
+ //its not a cracefull exit becuse fires dll loading error
+ //need better solution.
+ //return FALSE;
+
+ //3.0 does not fire error, while 2.0 does
+ //gr, 3.0 does as well
+ (*getNumDescs())=0;
+ (*getFirstDesc())=NULL;
+ printf("Skipping shave shaders for Vray 3.0.\n");fflush(stdout);
+ } else
+ printf("Shave shaders for Vray 3.0 loaded.\n");fflush(stdout);
+#else
+ if(vr_rev >= 0x30000)
+ {
+ //its not a cracefull exit becuse fires dll loading error
+ //need better solution.
+ //return FALSE;
+
+ (*getNumDescs())=0;
+ (*getFirstDesc())=NULL;
+ printf("Skipping shave shaders for Vray 2.0.\n");fflush(stdout);
+ } else
+ printf("Shave shaders for Vray 2.0 loaded.\n");fflush(stdout);
+#endif
+#endif
+ char* temp = getenv("TEMP");
+ char path[MAX_PATH];
+#ifdef DO_LOGS
+ sprintf(path,"%s/vray_Shave.log",temp);
+ alog = fopen(path,"w");
+ LOGMSG("DLL", "shaveVrayShader DLL loaded.")
+#endif
+ // Don't init Shave here; do that on demand in the shaveVrayPlugin::renderBegin().
+ // In this way Shave is not initialized at all if it is not used in the scene.
+ // SHAVE2init();
+ }
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+ // Do not cleanup Shave here; do that in the hostDetach() method of the plugin
+ // descriptor. This is because SHAVE2cleanup() cleans up some threads and it waits for them
+ // to complete, however calls to DllMain() are serialized and SHAVE2cleanup() may
+ // hang indefinitely as some threads attempt to call DllMain() for DLL_THREAD_DETACH.
+ // SHAVE2cleanup();
+ printf("Shave shaders for Vray unloaded.\n");fflush(stdout);
+#ifdef DO_LOGS
+ if(alog)
+ {
+ LOGMSG("DLL", "shaveVrayShader DLL unloaded.")
+ fclose(alog);
+ alog = NULL;
+ }
+#endif
+ }
+ break;
+ }
+ return TRUE;
+}
+
+
+#ifdef _MANAGED
+#pragma managed(pop)
+#endif
+#endif
+
+
diff --git a/vrayPlug/plugin/shaderMain.cpp b/vrayPlug/plugin/shaderMain.cpp
new file mode 100644
index 0000000..1cee2bc
--- /dev/null
+++ b/vrayPlug/plugin/shaderMain.cpp
@@ -0,0 +1,51 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+// shaderMain.cpp : Defines the entry point for the DLL application.
+//
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include "hairAPIvray.h"
+#include "shaveVrayBaseBSDFPool.h"
+
+#ifdef WIN32
+#ifdef _MANAGED
+#pragma managed(push, off)
+#endif
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+#ifdef _MANAGED
+#pragma managed(pop)
+#endif
+
+SHAVEVRAYSH_API IShaveBSDFPool* CreateShaveBSDFPool()
+{
+ return new shaveVrayBaseBSDFPool();
+}
+#else //linux
+extern "C" IShaveBSDFPool* CreateShaveBSDFPool()
+{
+ return new shaveVrayBaseBSDFPool();
+}
+#endif
+
+
diff --git a/vrayPlug/plugin/shaveSDKCALLBACKS.c b/vrayPlug/plugin/shaveSDKCALLBACKS.c
new file mode 100644
index 0000000..c46b55d
--- /dev/null
+++ b/vrayPlug/plugin/shaveSDKCALLBACKS.c
@@ -0,0 +1,97 @@
+//********************************************************
+//
+// Sample callback functions
+//
+//********************************************************
+
+#include "shaveSDKTYPES.h"
+#include "shaveSDKCALLBACKS2.h"
+
+
+void SHAVE2apply_inst_color(WFTYPE *instance_geom, int hairID, int slgID, unsigned long shaveINSTID)
+{
+}
+
+VERT SHAVE2displace_root(VERT *root,CURVEINFO *ci,int ID)
+{
+ VERT ret;
+ ret.x=0;
+ ret.y=0;
+ ret.z=0;
+ return ret;
+}
+
+
+int SHAVE2progress(int actual, int estimated_total)
+{
+ int killit=0;
+ return killit;
+}
+
+
+void SHAVE2coord_convertTOSHAVE(VERT *in)
+{
+}
+
+
+void SHAVE2coord_convertFROMSHAVE(VERT *in)
+{
+}
+
+
+float SHAVE2apply_texture(CURVEINFO *ci,VERT rest_root_worldpos,unsigned long shaveINSTID, int parm, float inbound_value)
+{
+ ci->u=20.0;
+ ci->v=2.0;
+
+ return inbound_value;
+}
+
+
+void MAYAexternal_forces(VERT *lastpos, VERT *velocity,int y)
+{
+}
+
+
+VERT SHAVE2apply_illumination(int LIGHTID, VERT wpos,VERT vector, VERT color)
+{
+ return color;
+}
+
+extern float SHAVE2apply_falloff(int lightNUM, VERT pos,float cone)
+{
+ return(cone);
+}
+
+
+void SHAVE2apply_illuminationWF(int LIGHTID, WFTYPE *samples)
+{
+}
+
+
+VERT SHAVE2apply_atmosphere(VERT wpos,VERT inbound_color )
+{
+ return(inbound_color);
+}
+
+
+float SHAVE2apply_VMAP(long SHAVE2INSTID,int VERTID,int chan, float inbound_value)
+{
+ return(inbound_value);
+}
+
+
+void MAYA2external_forces(VERT *lastpos, VERT *velocity,int y)
+{
+}
+
+void MAYA2cache_forces(int clearCache)
+{}
+
+void MAYA2apply_cached_forces(int guideNum, int vertNum, VERT* velocity)
+{}
+
+void SHAVEdraw_tile_callback2(VERT *a, VERT *b)
+{
+}
+
diff --git a/vrayPlug/plugin/shaveVray-vs11.sln b/vrayPlug/plugin/shaveVray-vs11.sln
new file mode 100644
index 0000000..4725832
--- /dev/null
+++ b/vrayPlug/plugin/shaveVray-vs11.sln
@@ -0,0 +1,35 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaveVray", "shaveVray-vs11.vcxproj", "{7540D2DC-D389-46B8-A894-B25EE6BCF0F1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ RelDbgV36|x64 = RelDbgV36|x64
+ Release|x64 = Release|x64
+ ReleaseVray36|x64 = ReleaseVray36|x64
+ ReleaseVray36-direct|x64 = ReleaseVray36-direct|x64
+ ReleaseVray40|x64 = ReleaseVray40|x64
+ ReleaseVray40-direct|x64 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Debug|x64.ActiveCfg = Debug|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Debug|x64.Build.0 = Debug|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.RelDbgV36|x64.ActiveCfg = RelDbgV36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.RelDbgV36|x64.Build.0 = RelDbgV36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Release|x64.ActiveCfg = Release|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Release|x64.Build.0 = Release|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36|x64.ActiveCfg = ReleaseVray36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36|x64.Build.0 = ReleaseVray36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36-direct|x64.ActiveCfg = ReleaseVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36-direct|x64.Build.0 = ReleaseVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40|x64.ActiveCfg = ReleaseVray40|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40|x64.Build.0 = ReleaseVray40|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40-direct|x64.ActiveCfg = ReleaseVray40-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40-direct|x64.Build.0 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vrayPlug/plugin/shaveVray-vs11.vcxproj b/vrayPlug/plugin/shaveVray-vs11.vcxproj
new file mode 100644
index 0000000..1c175dc
--- /dev/null
+++ b/vrayPlug/plugin/shaveVray-vs11.vcxproj
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="RelDbgV36|x64">
+ <Configuration>RelDbgV36</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36-direct|x64">
+ <Configuration>ReleaseVray36-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36|x64">
+ <Configuration>ReleaseVray36</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40-direct|x64">
+ <Configuration>ReleaseVray40-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40|x64">
+ <Configuration>ReleaseVray40</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>shaveVray</ProjectName>
+ <ProjectGuid>{7540D2DC-D389-46B8-A894-B25EE6BCF0F1}</ProjectGuid>
+ <RootNamespace>shaveVray</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(AUTODESK_LOCATION)\Maya2017\vray\vrayplugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vray_Shave</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">vray_Shave40</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">vray_Shave40</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shaveSDK2.lib;Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib ;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;..\include22_win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray22\win64vc101;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc11;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelDbgV36|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc11;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY40;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc11;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc11;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY40;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc11;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="pluginMain.cpp" />
+ <ClCompile Include="shaveVrayDesc.cpp" />
+ <ClCompile Include="shaveVrayInstance.cpp" />
+ <ClCompile Include="shaveVrayInstanceBase.cpp" />
+ <ClCompile Include="shaveVrayInstanceI.cpp" />
+ <ClCompile Include="shaveVrayMovingTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayMovingVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayPlugin.cpp" />
+ <ClCompile Include="shaveVrayShadeable.cpp" />
+ <ClCompile Include="shaveVrayShadeData.cpp" />
+ <ClCompile Include="shaveVraySharedFunctions.cpp" />
+ <ClCompile Include="shaveVrayStaticTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayStaticVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayTriShadeable.cpp" />
+ <ClCompile Include="shaveVrayTriShadeData.cpp" />
+ <ClCompile Include="shaveVrayTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayVoxelPrim.cpp" />
+ <ClCompile Include="hairAPIimp.cpp" />
+ <ClCompile Include="shaveSDKCALLBACKS.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shaveVrayDesc.h" />
+ <ClInclude Include="shaveVrayInstance.h" />
+ <ClInclude Include="shaveVrayInstanceBase.h" />
+ <ClInclude Include="shaveVrayInstanceI.h" />
+ <ClInclude Include="shaveVrayMovingTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayMovingVoxelPrim.h" />
+ <ClInclude Include="shaveVrayPlugin.h" />
+ <ClInclude Include="shaveVrayShadeable.h" />
+ <ClInclude Include="shaveVrayShadeData.h" />
+ <ClInclude Include="shaveVraySharedFunctions.h" />
+ <ClInclude Include="shaveVrayStaticTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayStaticVoxelPrim.h" />
+ <ClInclude Include="shaveVrayTriShadeable.h" />
+ <ClInclude Include="shaveVrayTriShadeData.h" />
+ <ClInclude Include="shaveVrayTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayVoxelPrim.h" />
+ <ClInclude Include="shaveVrayVoxelPrimBase.h" />
+ <ClInclude Include="hairAPI.h" />
+ <ClInclude Include="hairAPIimp.h" />
+ <ClInclude Include="hairAPIvray.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vrayPlug/plugin/shaveVray-vs15.sln b/vrayPlug/plugin/shaveVray-vs15.sln
new file mode 100644
index 0000000..954fad0
--- /dev/null
+++ b/vrayPlug/plugin/shaveVray-vs15.sln
@@ -0,0 +1,40 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaveVray", "shaveVray-vs15.vcxproj", "{7540D2DC-D389-46B8-A894-B25EE6BCF0F1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ DebugVray36-direct|x64 = DebugVray36-direct|x64
+ DebugVray40-direct|x64 = DebugVray40-direct|x64
+ Release|x64 = Release|x64
+ ReleaseVray36|x64 = ReleaseVray36|x64
+ ReleaseVray36-direct|x64 = ReleaseVray36-direct|x64
+ ReleaseVray40|x64 = ReleaseVray40|x64
+ ReleaseVray40-direct|x64 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Debug|x64.ActiveCfg = Debug|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Debug|x64.Build.0 = Debug|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.DebugVray36-direct|x64.ActiveCfg = DebugVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.DebugVray36-direct|x64.Build.0 = DebugVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.DebugVray40-direct|x64.ActiveCfg = DebugVray40-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.DebugVray40-direct|x64.Build.0 = DebugVray40-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Release|x64.ActiveCfg = Release|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.Release|x64.Build.0 = Release|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36|x64.ActiveCfg = ReleaseVray36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36|x64.Build.0 = ReleaseVray36|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36-direct|x64.ActiveCfg = ReleaseVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray36-direct|x64.Build.0 = ReleaseVray36-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40|x64.ActiveCfg = ReleaseVray40|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40|x64.Build.0 = ReleaseVray40|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40-direct|x64.ActiveCfg = ReleaseVray40-direct|x64
+ {7540D2DC-D389-46B8-A894-B25EE6BCF0F1}.ReleaseVray40-direct|x64.Build.0 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vrayPlug/plugin/shaveVray-vs15.vcxproj b/vrayPlug/plugin/shaveVray-vs15.vcxproj
new file mode 100644
index 0000000..2642c47
--- /dev/null
+++ b/vrayPlug/plugin/shaveVray-vs15.vcxproj
@@ -0,0 +1,453 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugVray36-direct|x64">
+ <Configuration>DebugVray36-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugVray40-direct|x64">
+ <Configuration>DebugVray40-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36-direct|x64">
+ <Configuration>ReleaseVray36-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36|x64">
+ <Configuration>ReleaseVray36</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40-direct|x64">
+ <Configuration>ReleaseVray40-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40|x64">
+ <Configuration>ReleaseVray40</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>shaveVray</ProjectName>
+ <ProjectGuid>{7540D2DC-D389-46B8-A894-B25EE6BCF0F1}</ProjectGuid>
+ <RootNamespace>shaveVray</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vray_Shave</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">vray_Shave40</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">vray_Shave40</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'">vray_Shave36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'">vray_Shave40</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shaveSDK2.lib;Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib ;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray36-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;_HAS_ITERATOR_DEBUGGING=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shaveSDK2DEBUG.lib;Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib ;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVray40-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY40;VRAY_DUAL;_HAS_ITERATOR_DEBUGGING=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shaveSDK2DEBUG.lib;Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib ;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;..\include22_win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray22\win64vc101;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY40;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY30;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\libexe\sample\include;$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_AFXDLL;NT_PLUGIN;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;HAIRVRAY_EXPORTS;HAIRAPI_STATIC;VRAY40;VRAY_DUAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level2</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DisableSpecificWarnings>
+ </DisableSpecificWarnings>
+ <AdditionalOptions>/wd4251 /wd4275 %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Ws2_32.lib;Netapi32.lib;vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;Rpcrt4.lib;shaveSDK2.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc14;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;libcpmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="pluginMain.cpp" />
+ <ClCompile Include="shaveVrayDesc.cpp" />
+ <ClCompile Include="shaveVrayInstance.cpp" />
+ <ClCompile Include="shaveVrayInstanceBase.cpp" />
+ <ClCompile Include="shaveVrayInstanceI.cpp" />
+ <ClCompile Include="shaveVrayMovingTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayMovingVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayPlugin.cpp" />
+ <ClCompile Include="shaveVrayShadeable.cpp" />
+ <ClCompile Include="shaveVrayShadeData.cpp" />
+ <ClCompile Include="shaveVraySharedFunctions.cpp" />
+ <ClCompile Include="shaveVrayStaticTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayStaticVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayTriShadeable.cpp" />
+ <ClCompile Include="shaveVrayTriShadeData.cpp" />
+ <ClCompile Include="shaveVrayTriVoxelPrim.cpp" />
+ <ClCompile Include="shaveVrayVoxelPrim.cpp" />
+ <ClCompile Include="hairAPIimp.cpp" />
+ <ClCompile Include="shaveSDKCALLBACKS.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shaveVrayDesc.h" />
+ <ClInclude Include="shaveVrayInstance.h" />
+ <ClInclude Include="shaveVrayInstanceBase.h" />
+ <ClInclude Include="shaveVrayInstanceI.h" />
+ <ClInclude Include="shaveVrayMovingTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayMovingVoxelPrim.h" />
+ <ClInclude Include="shaveVrayPlugin.h" />
+ <ClInclude Include="shaveVrayShadeable.h" />
+ <ClInclude Include="shaveVrayShadeData.h" />
+ <ClInclude Include="shaveVraySharedFunctions.h" />
+ <ClInclude Include="shaveVrayStaticTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayStaticVoxelPrim.h" />
+ <ClInclude Include="shaveVrayTriShadeable.h" />
+ <ClInclude Include="shaveVrayTriShadeData.h" />
+ <ClInclude Include="shaveVrayTriVoxelPrim.h" />
+ <ClInclude Include="shaveVrayVoxelPrim.h" />
+ <ClInclude Include="shaveVrayVoxelPrimBase.h" />
+ <ClInclude Include="hairAPI.h" />
+ <ClInclude Include="hairAPIimp.h" />
+ <ClInclude Include="hairAPIvray.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vrayPlug/plugin/shaveVrayBaseBSDF.cpp b/vrayPlug/plugin/shaveVrayBaseBSDF.cpp
new file mode 100644
index 0000000..3211508
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayBaseBSDF.cpp
@@ -0,0 +1,325 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayBaseBSDF.h ( was HairVrBaseBSDF.h )
+
+ DESCRIPTION: Generic class for BSDFs
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 09-09-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayBaseBSDF.h"
+
+
+void shaveVrayBaseBSDF::init(const VR::VRayContext &rc,
+ const VR::Color &reflectionColor,
+ const VR::Color &diffuseColor,
+ const VR::Color &ambientColor,
+ const VR::Color &specularTint,
+ const VR::Color &specularTint2,
+ float ambDiff,
+ float specularLevel,
+ float reflectionGlossiness, int ns,
+ const VR::Color &transp,
+ const VR::ShadeVec &hairDir,
+ float requiredTransparency,
+ bool cameraVisibility,
+ bool reflVisibility,
+ bool refrVisibility,
+ bool lightVisibility,
+ bool giVisibility,
+ float selfshadow,
+ bool recvshadow)
+{
+ this->hairDir=hairDir;
+
+ // Russian roulette for the transparency for camera rays; this drastically
+ // improves render times for soft transprent hair by reducing the number of
+ // lighting calculations, for roughly the same visual result. It could be
+ // slightly noisier, but the speed gain is worth it.
+ if (rc.rayresult.transpLevel>0 && 0==(rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_INDIRECT | VR::RT_LIGHT | VR::RT_LIGHTMAP))) {
+ float t=const_cast<VR::VRayContext&>(rc).getDMCValue();
+ if (t<requiredTransparency) {
+ requiredTransparency=1.0f;
+ } else {
+ requiredTransparency=0.0f;
+ }
+ requiredTransparency=VR::clamp(requiredTransparency, 0.0f, 1.0f);
+ }
+ ///////////////
+ if(((rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_LIGHT | VR::RT_LIGHTMAP)) != 0) && !lightVisibility)
+ {
+ requiredTransparency=1.0f;
+ }
+ else if(((rc.rayparams.rayType & VR::RT_INDIRECT) != 0) && !giVisibility)
+ {
+ requiredTransparency=1.0f;
+ }
+ else if(rc.rayparams.totalLevel == 0 && !cameraVisibility)
+ {
+ requiredTransparency=1.0f;
+ }
+ else if(rc.rayparams.totalLevel != 0)
+ {
+ if((rc.rayparams.rayType & VUtils::RT_REFLECT) && !reflVisibility)
+ requiredTransparency=1.0f;
+ else if((rc.rayparams.rayType & VUtils::RT_REFRACT) && !refrVisibility)
+ requiredTransparency=1.0f;
+
+ }
+ ////// self shadowing /////////
+ //printf("selfshadow %f\n",selfshadow);fflush(stdout);
+ if(recvshadow)
+ {
+ if(selfshadow != 1.0f && requiredTransparency!=1.0f)
+ {
+ if ((rc.rayparams.rayType & VR::RT_SHADOW)!=0
+ && rc.parent!=NULL && rc.parent->rayresult.sd==rc.rayresult.sd)
+ {
+ //requiredTransparency=1.0f;
+ requiredTransparency = (1.0f - selfshadow);
+ }
+ }
+ }
+ //else if (requiredTransparency!=1.0f && (rc.rayparams.rayType & VR::RT_SHADOW)!=0
+ // && rc.parent!=NULL && rc.parent->rayresult.sd!=rc.rayresult.sd)
+ //{
+ // requiredTransparency=1.0f;
+ //}
+
+ this->requiredTransparency=requiredTransparency;
+ this->isGatherPoint = rc.vray->getSequenceData().globalLightManager->isGatheringPoint(rc) != 0;
+
+ float contrib=(1.0f-requiredTransparency); // *0.5f;
+
+ _reflect_filter() = VR::toShadeCol(reflectionColor)*contrib*0.5f;
+ _transparency() = VR::toShadeCol(transp);
+ _diffuse() = VR::toShadeCol(diffuseColor)*contrib;
+ _ambient() = VR::toShadeCol(ambientColor);
+ _spec_tint() = VR::toShadeCol(specularTint);
+ _spec_tint2() = VR::toShadeCol(specularTint2);
+ _ambdiff() = ambDiff;
+ _speclvl() = specularLevel;
+ _cameraVisibility() = cameraVisibility;
+ _lightVisibility() = lightVisibility;
+ _giVisibility() = giVisibility;
+ _combineSampling()= rc.vray->getSequenceData().globalLightManager->isGatheringPoint(rc) != 0;
+
+ float divd=(reflectionGlossiness*70.0f);
+ divd*=divd;
+ if (divd<1e-6f) {
+ _glossiness()=0.0f;
+ } else {
+ _glossiness() = divd;
+ }
+ _normal() = rc.rayresult.normal;
+ _gnormal()= rc.rayresult.gnormal;
+
+
+}
+/*
+| from BRDFSampler
+*/
+VR::ShadeCol shaveVrayBaseBSDF::getDiffuseColor(VR::ShadeCol &lightColor)
+{
+ VR::ShadeCol res=lightColor*diffuse();
+ lightColor*=currentTransp;
+ //performance test
+ //lightColor.makeZero();
+ return res;
+}
+/*
+| from BRDFSampler
+*/
+VR::ShadeCol shaveVrayBaseBSDF::getLightMult(VR::ShadeCol &lightColor)
+{
+ VR::ShadeCol res = lightColor*diffuse();
+ lightColor*=currentTransp;
+ //performance test
+ //lightColor.makeZero();
+ return res;
+}
+/*
+| from BRDFSampler
+*/
+
+VR::ShadeCol getColorFromDir(const VR::Vector &a) {
+ return VR::ShadeCol(a.x, a.y, a.z)*0.5f+VR::ShadeCol(0.5f, 0.5f, 0.5f);
+}
+
+// This is based on Kajiya, J. T. and Kay, T. L., "Rendering Fur with Three Dimensional Texures",
+// in SIGGRAPH '89: Proceedings of the 16th annual conference on Computer graphics and interactive techniques
+inline VR::real getGlossyProbability(const VR::ShadeVec &direction, const VR::ShadeVec &viewDir, const VR::ShadeVec &hairDir, float p)
+{
+ float cs1=(float) (direction*hairDir);
+ float sn1=sqrtf(VR::Max(0.0f, 1.0f-cs1*cs1));
+
+ float cs=(float) (viewDir*hairDir);
+ float sn=sqrtf(VR::Max(0.0f, 1.0f-cs*cs));
+
+ float k = VR::Max(0.0f, cs1*cs+sn1*sn);
+ k=powf(k, p);
+
+ return k;
+}
+
+VR::ShadeCol shaveVrayBaseBSDF::eval(const VR::VRayContext &rc, const VR::ShadeVec &direction,
+ VR::ShadeCol &lightColor, VR::ShadeCol &origLightColor, float probLight, int flags)
+{
+ //if(((rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_LIGHT | VR::RT_LIGHTMAP)) != 0) && !lightVisibility())
+ //{
+ // return VR::ShadeCol(0.0f, 0.0f, 0.0f);
+ //}
+ //else if(((rc.rayparams.rayType & VR::RT_INDIRECT) != 0) && !giVisibility())
+ //{
+ // return VR::ShadeCol(0.0f, 0.0f, 0.0f);
+ //}
+ //else if(rc.rayparams.totalLevel == 0 && !cameraVisibility())
+ //{
+ // return origLightColor;//VR::ShadeCol(0.0f, 0.0f, 0.0f);
+ //}
+
+ float cs0=(float) (direction*rc.rayresult.normal);
+ VR::ShadeVec d2;
+ if (cs0<0.0f) return VR::ShadeCol(0.0f, 0.0f, 0.0f);
+
+ float cs=(float) (direction*hairDir);
+
+ ///////////// performance test //////////////
+ ///////////// white-like BSDF /////////////
+ //VR::ShadeCol res;
+ //if ((flags & FBRDF_DIFFUSE)==0) res.makeZero();
+ //else {
+ // float k=cs;
+ // // Apply combined sampling ONLY if GI is on which will pick up the rest of the result
+ // if (isGatherPoint) {
+ // float probReflection=k*2.0f;
+ // probReflection*=probReflection;
+ // probLight*=probLight;
+ // k*=probLight/(probLight+probReflection);
+ // }
+ // res=lightColor*k;
+ //}
+ //lightColor.makeZero();
+ //origLightColor.makeZero();
+ //return res;
+ ////////////////////////////////////////////
+
+ VR::ShadeCol res;
+ VR::ShadeCol diff;
+ VR::ShadeCol spec;
+ VR::ShadeCol spec2;
+
+ res.makeZero();
+ diff.makeZero();
+ spec.makeZero();
+ spec2.makeZero();
+
+ //use spec_tint() and spec_tint2() - to get speclar colors
+ //test
+ //printf("spec_tint %f %f %f \n",spec_tint().r, spec_tint().g, spec_tint().b);
+ //printf("spec_tint2 %f %f %f \n",spec_tint2().r, spec_tint2().g, spec_tint2().b);
+
+ //if(isGatherPoint)//does not make a difference for perfromance -- 01-11-2010
+ {
+ if (flags & FBRDF_DIFFUSE)
+ {
+ float sn=sqrtf(VR::Max(0.0f, 1.0f-cs*cs));
+ float K = sn*ambdiff() + (1.0f - ambdiff());
+ diff = (lightColor*diffuse())*K;
+ }
+ if (glossiness() > 0.0f && (flags & FBRDF_SPECULAR) &&
+ ((rc.rayparams.rayType & VR::RT_NOSPECULAR)==0))
+ {
+ VUtils::real k = getGlossyProbability(direction, rc.rayparams.viewDir, hairDir, glossiness());
+ if (k>1.0f) k=1.0f;
+ spec = (speclvl()*k)*(reflect_filter()*lightColor);
+ spec *= spec_tint();
+ d2=direction*.7+rc.rayparams.viewDir*.3;
+ d2.makeNormalized0();
+
+ VUtils::real k2 = getGlossyProbability(d2, rc.rayparams.viewDir, hairDir, glossiness()*.55f);
+ if (k2>1.0f) k2=1.0f;
+ spec2 = (speclvl()*k2)*(reflect_filter()*lightColor);
+ spec2 *= spec_tint2();
+ }
+
+ lightColor*=currentTransp;
+ origLightColor*=currentTransp;
+
+ res = diff + spec+spec2;
+ }
+ return res;
+}
+/*
+| from BRDFSampler
+*/
+VR::ShadeCol shaveVrayBaseBSDF::getTransparency(const VR::VRayContext &rc)
+{
+ return VR::ShadeCol(currentTransp, currentTransp, currentTransp);
+}
+
+void shaveVrayBaseBSDF::traceForward(VR::VRayContext &rc, int doDiffuse)
+{
+ if (!doDiffuse)
+ rc.mtlresult.color.makeZero();
+ else
+ rc.mtlresult.color=diffuse()*rc.evalDiffuse();
+
+// joe dec23 if(requiredTransparency < 0.0001f)
+ if ((requiredTransparency < 0.15f)||( (rc.rayparams.rayType & VR::RT_CAMERA)==0 ) )
+ {
+ rc.mtlresult.transp.set(0.0f, 0.0f, 0.0f);
+ rc.mtlresult.alpha.set(1.0f, 1.0f, 1.0f);
+// rc.mtlresult.alphaTransp=rc.mtlresult.transp;
+ rc.mtlresult.alphaTransp.set(0.0f, 0.0f, 0.0f);
+ }
+ else
+ {
+ rc.mtlresult.transp.set(requiredTransparency, requiredTransparency, requiredTransparency);
+ rc.mtlresult.alpha=rc.mtlresult.transp.whiteComplement();
+ rc.mtlresult.alphaTransp=rc.mtlresult.transp;
+ }
+
+ VR::Fragment *f=rc.mtlresult.fragment;
+ if (f) {
+ const VR::ShadeCol diffColor=diffuse();
+ const VR::ShadeCol rawGI(rc.evalDiffuse());
+ const VR::ShadeCol finalGI = rawGI * diffColor;
+ f->setChannelDataByAlias(REG_CHAN_VFB_DIFFUSE, &diffColor);
+
+ // raw GI shows the light contribution from the GI
+ f->setChannelDataByAlias(REG_CHAN_VFB_RAWGI, &rawGI);
+ f->setChannelDataByAlias(REG_CHAN_VFB_GI, &finalGI);
+ }
+}
+
+/*
+| from BRDFSampler
+*/
+VR::RenderChannelsInfo* shaveVrayBaseBSDF::getRenderChannels()
+{
+ return &VR::RenderChannelsInfo::reflectChannels;
+}
+
+/*
+| from BSDFSampler
+*/
+VR::BRDFSampler* shaveVrayBaseBSDF::getBRDF(VR::BSDFSide side)
+{
+ if (side == VR::bsdfSide_front)
+ currentTransp=(1.0f+requiredTransparency)*0.5f;
+ else
+ currentTransp=2.0f*requiredTransparency/(1.0f+requiredTransparency);
+
+ return static_cast<VR::BRDFSampler*>(this);
+}
+
diff --git a/vrayPlug/plugin/shaveVrayBaseBSDF.h b/vrayPlug/plugin/shaveVrayBaseBSDF.h
new file mode 100644
index 0000000..4216b8d
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayBaseBSDF.h
@@ -0,0 +1,137 @@
+#ifndef _HAIR_VR_BASE_BSDF_H_
+#define _HAIR_VR_BASE_BSDF_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayBaseBSDF.h ( was HairVrBaseBSDF.h )
+
+ DESCRIPTION: Generic class for BSDFs
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 09-09-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+//#include <max.h> //ShadeContext
+//#include <vraybase.h>
+//#include <vectorbase.h>
+//#include <vrayinterface.h>
+//#include <vrayplugins.h>
+//#include <vraygeom.h>
+
+#include "utils.h"
+#include "vrayplugins.h"
+#include "brdfs.h"
+
+#include "hairAPIvray.h"
+#include "vray3_compat.h"
+
+class shaveVrayBaseBSDF : public IShaveVrayBSDF
+ //public VR::BRDFSampler,
+ //public VR::BSDFSampler
+{
+public:
+ // Initialization
+ void init(const VR::VRayContext &rc,
+ const VR::Color &reflectionColor,
+ const VR::Color &diffuseColor,
+ const VR::Color &ambientColor,
+ const VR::Color &specularTint,
+ const VR::Color &specularTint2,
+ float ambDiff,
+ float specularLevel,
+ float reflectionGlossiness,
+ int subdivs, const VR::Color &transp,
+ const VR::ShadeVec &hairDir,
+ float requiredTransparency,
+ bool cameraVisibility,
+ bool reflVisibility,
+ bool refrVisibility,
+ bool lightVisibility,
+ bool giVisibility,
+ float selfshadow,
+ bool recvshadow) VRAY_OVERRIDE;
+
+ // From BRDFSampler
+ VR::ShadeCol getDiffuseColor(VR::ShadeCol &lightColor) VRAY_OVERRIDE;
+ VR::ShadeCol getLightMult (VR::ShadeCol &lightColor) VRAY_OVERRIDE;
+ VR::ShadeCol getTransparency(const VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ VR::ShadeCol eval(const VR::VRayContext &rc, const VR::ShadeVec &direction,
+ VR::ShadeCol &lightColor, VR::ShadeCol &origLightColor, float probLight, int flags) VRAY_OVERRIDE;
+
+ void traceForward(VR::VRayContext &rc, int doDiffuse) VRAY_OVERRIDE;
+
+ VR::RenderChannelsInfo* getRenderChannels() VRAY_OVERRIDE;
+
+ // From BSDFSampler
+ VR::BRDFSampler *getBRDF(VR::BSDFSide side) VRAY_OVERRIDE;
+protected:
+
+ //const member access
+ inline const VR::ShadeCol& reflect_filter() const {return m_reflect_filter;}
+ inline const VR::ShadeCol& transparency() const {return m_transparency;}
+ inline const VR::ShadeCol& diffuse() const {return m_diffuse;}
+ inline const VR::ShadeCol& ambient() const {return m_ambient;}
+ inline const VR::ShadeCol& spec_tint() const {return m_spec_tint;}
+ inline const VR::ShadeCol& spec_tint2() const {return m_spec_tint2;}
+ inline const VR::ShadeVec& normal() const {return m_normal; }
+ inline const VR::ShadeVec& gnormal() const {return m_gnormal;}
+ inline VR::real glossiness() const {return m_glossiness;}
+ inline bool combineSampling() const {return m_combineSampling;}
+ inline float ambdiff() const {return m_ambdiff;}
+ inline float speclvl() const {return m_speclvl;}
+ inline bool cameraVisibility() const {return m_cameraVisibility;}
+ inline bool lightVisibility() const {return m_lightVisibility;}
+ inline bool giVisibility() const {return m_giVisibility;}
+
+ //member access
+ inline VR::ShadeCol& _reflect_filter() {return m_reflect_filter;}
+ inline VR::ShadeCol& _transparency() {return m_transparency;}
+ inline VR::ShadeCol& _diffuse() {return m_diffuse;}
+ inline VR::ShadeCol& _ambient() {return m_ambient;}
+ inline VR::ShadeCol& _spec_tint() {return m_spec_tint;}
+ inline VR::ShadeCol& _spec_tint2() {return m_spec_tint2;}
+ inline VR::ShadeVec& _normal() {return m_normal; }
+ inline VR::ShadeVec& _gnormal() {return m_gnormal;}
+ inline VR::real& _glossiness() {return m_glossiness;}
+ inline bool& _combineSampling() {return m_combineSampling;}
+ inline float& _ambdiff() {return m_ambdiff;}
+ inline float& _speclvl() {return m_speclvl;}
+ inline bool& _cameraVisibility() {return m_cameraVisibility;}
+ inline bool& _lightVisibility() {return m_lightVisibility;}
+ inline bool& _giVisibility() {return m_giVisibility;}
+
+private:
+ VR::ShadeCol m_reflect_filter;
+ VR::ShadeCol m_transparency;
+ VR::ShadeCol m_diffuse;
+ VR::ShadeCol m_ambient;
+ VR::ShadeCol m_spec_tint;
+ VR::ShadeCol m_spec_tint2;
+ VR::real m_glossiness;
+ float m_ambdiff;
+ float m_speclvl;
+ bool m_combineSampling;
+ bool m_cameraVisibility;
+ bool m_lightVisibility;
+ bool m_giVisibility;
+
+ VR::ShadeVec m_normal;
+ VR::ShadeVec m_gnormal;
+
+ VR::ShadeVec hairDir;
+ float currentTransp;
+ float requiredTransparency;
+ bool isGatherPoint;
+};
+
+#endif //endof_HAIR_VR_BASE_BSDF_H_
+
diff --git a/vrayPlug/plugin/shaveVrayBaseBSDFPool.cpp b/vrayPlug/plugin/shaveVrayBaseBSDFPool.cpp
new file mode 100644
index 0000000..823c2ed
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayBaseBSDFPool.cpp
@@ -0,0 +1,25 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "shaveVrayBaseBSDFPool.h"
+
+
+void shaveVrayBaseBSDFPool::init(VR::VRayCore *vray)
+{
+ const VR::VRaySequenceData &sdata=vray->getSequenceData();
+ _bsdfPool().init(sdata.maxRenderThreads);
+}
+void shaveVrayBaseBSDFPool::freeMem()
+{
+ _bsdfPool().freeMem();
+}
+IShaveVrayBSDF* shaveVrayBaseBSDFPool::newBRDF(const VR::VRayContext &rc)
+{
+ return _bsdfPool().newBRDF(rc);
+}
+void shaveVrayBaseBSDFPool::deleteBRDF(const VR::VRayContext &rc, IShaveVrayBSDF* bsdf)
+{
+ shaveVrayBaseBSDF* dbsdf = static_cast<shaveVrayBaseBSDF*>(bsdf);
+ _bsdfPool().deleteBRDF(rc, dbsdf);
+}
diff --git a/vrayPlug/plugin/shaveVrayBaseBSDFPool.h b/vrayPlug/plugin/shaveVrayBaseBSDFPool.h
new file mode 100644
index 0000000..d8968cb
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayBaseBSDFPool.h
@@ -0,0 +1,30 @@
+#ifndef _HAIR_BASE_BSDF_POOL_H_
+#define _HAIR_BASE_BSDF_POOL_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "hairAPIvray.h"
+#include "shaveVrayBaseBSDF.h"
+
+class shaveVrayBaseBSDFPool : public IShaveBSDFPool {
+public:
+ shaveVrayBaseBSDFPool(){}
+ virtual ~shaveVrayBaseBSDFPool(){}
+
+ void init(VR::VRayCore *vray);
+ void freeMem();
+
+ IShaveVrayBSDF* newBRDF(const VR::VRayContext &rc);
+ void deleteBRDF(const VR::VRayContext &rc, IShaveVrayBSDF* bsdf);
+
+protected:
+ inline const VR::BRDFPool<shaveVrayBaseBSDF>& bsdfPool() const {return m_bsdfPool;}
+ inline VR::BRDFPool<shaveVrayBaseBSDF>& _bsdfPool() {return m_bsdfPool;}
+private:
+ VR::BRDFPool<shaveVrayBaseBSDF> m_bsdfPool;
+};
+
+
+#endif
diff --git a/vrayPlug/plugin/shaveVrayDesc.cpp b/vrayPlug/plugin/shaveVrayDesc.cpp
new file mode 100644
index 0000000..794f1a8
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayDesc.cpp
@@ -0,0 +1,26 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayDesc.cpp
+
+ DESCRIPTION: Vray plugin descriptor
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 29-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayDesc.h"
+
+//VR::VRayPluginDesc* GetHairVrayDesc()
+//{
+// static shaveVrayDesc theDesc;
+// return &theDesc;
+//}
+//
+//tchar* shaveVrayDesc::pluginName = "hairVRayShader";
diff --git a/vrayPlug/plugin/shaveVrayDesc.h b/vrayPlug/plugin/shaveVrayDesc.h
new file mode 100644
index 0000000..15dbbf7
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayDesc.h
@@ -0,0 +1,20 @@
+#ifndef _HAIR_VRAY_DESC_H_
+#define _HAIR_VRAY_DESC_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "vrayplugins.h"
+#include "shaveVrayPlugin.h"
+
+#if defined(VRAY30) || defined(VRAY40)
+#define shaveVrayPluginID PluginID(LARGE_CONST(0xFFFF000011130002))
+#define shaveVrayPluginName "hairVRay30Shader"
+#else
+#define shaveVrayPluginID PluginID(LARGE_CONST(0xFFFF000011130001))
+#define shaveVrayPluginName "hairVRayShader"
+#endif
+
+#endif
+
diff --git a/vrayPlug/plugin/shaveVrayInstance.cpp b/vrayPlug/plugin/shaveVrayInstance.cpp
new file mode 100644
index 0000000..65b9806
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstance.cpp
@@ -0,0 +1,233 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstance.cpp
+
+ DESCRIPTION: VRay mesh instance for regular hair
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 30-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayInstance.h"
+#include "shaveVrayMovingVoxelPrim.h"
+#include "shaveVrayStaticVoxelPrim.h"
+
+
+shaveVrayInstance::shaveVrayInstance(
+ shaveVrayPlugin *vplugin,
+ VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#if defined(VRAY30)
+ const VR::TraceTransform &baseTM,
+#elif defined(VRAY40)
+ const VR::Transform &baseTM,
+#endif
+ int objectID,
+ const tchar *userAttributes, int primaryVisibility)
+ :
+#if defined(VRAY30)
+ VR::BaseMeshInstance(vplugin, vplugin, mtl, bsdf, renderID, volume, lightList, baseTM, objectID, userAttributes, primaryVisibility),
+#elif defined(VRAY40)
+ VR::BaseInstance(vplugin, mtl, bsdf, renderID, volume, lightList, baseTM, objectID, userAttributes, primaryVisibility),
+#endif
+ shaveVrayInstanceBase(vplugin)
+{
+ _hair() = NULL;
+ _stackid() = plugin->GetStackIndex();
+ _squirrel()= plugin->GetSquirrel();
+ _tipfade() = plugin->GetTipFade();
+ _ownbsdf() = plugin->GetUseOwnBSDF();
+ _spectint()= plugin->GetSpecTint();
+ _spectint2()= plugin->GetSpecTint2();
+ _cameraVisibility() = plugin->GetCameraVisibility();
+ _reflVisibility()= plugin->GetReflVisibility();
+ _refrVisibility()= plugin->GetRefrVisibility();
+ _lightVisibility() = plugin->GetLightVisibility();
+ _giVisibility() = plugin->GetGiVisibility();
+ _selfshadow() = plugin->GetSelfShadow();
+ _recvshadow() = plugin->GetRecvShadow();
+
+ //printf("get selfShadow %f\n",plugin->GetSelfShadow());fflush(stdout);
+
+ _shdata() = new shaveVrayShadeData(this);
+
+}
+
+shaveVrayInstance::~shaveVrayInstance()
+{
+ if(shdata())
+ delete shdata();
+}
+
+void shaveVrayInstance::compileGeometry(
+ VR::VRayRenderer *vray,
+#if defined(VRAY30)
+ VR::TraceTransform *tm,
+#elif defined(VRAY40)
+ const VR::Transform *tm,
+#endif
+ double *times, int tmCount)
+{
+ LOGMSG("SHAVE", "shaveVrayInstance::compileGeometry");
+ LOGMSGI("SHAVE", "id",stackid());
+
+ loadHair();
+
+ if(!hair())
+ return;
+
+#if defined(VRAY30) || defined(VRAY40)
+ LOGMSG("SHAVE", plugin->useGlobalHairTree ? "useGlobalHairTree - yes":"useGlobalHairTree - no");
+#endif
+
+#if defined(VRAY30)
+ BaseMeshInstance::compileGeometry(vray, tm, times, tmCount);
+#elif defined(VRAY40)
+ BaseInstance::compileGeometry(vray, tm, times, tmCount);
+#endif
+
+ int num_voxels = hair()->GetNumVoxels();
+#if defined(VRAY30)
+ VR::RayServerInterface2 *rayserver = vray->getRayServer();
+#else
+ VR::RayServerInterface *rayserver = vray->getRayServer();
+#endif
+ int rendID = rayserver->getNewRenderIDArray(num_voxels/*100*//*0*/);
+
+ const VR::VRaySequenceData& sdata = vray->getSequenceData();
+ bool blurOn = sdata.params.moblur.on != 0;
+
+
+
+ //tm is not animated
+ if (/*tmCount == 1*/ !blurOn )
+ {
+ for(int i = 0; i < num_voxels; i++)
+ {
+ IHairVoxel* voxel = hair()->GetVoxel(i);
+ if(voxel)
+ {
+ shaveVrayStaticVoxelPrim* vox_prim = new shaveVrayStaticVoxelPrim(voxel,vray,this);
+
+ vox_prim->SetTipFade(tipfade());
+ vox_prim->SetUseOwnBSDF(ownbsdf());
+ vox_prim->SetSpecTint(spectint());
+ vox_prim->SetSpecTint2(spectint2());
+ //vox_prim->SetAmbient(ambient());
+#if defined(VRAY30) || defined(VRAY40)
+#if VRAY_DLL_VERSION >= 0x36000
+ int primary_visibility = getPrimaryVisibility();
+#endif
+ if (plugin->useGlobalHairTree && primary_visibility)
+ {
+ vox_prim->storeInGlobalTree(rayserver);
+ _voxprims().push_back(vox_prim);
+ }
+ else
+ {
+ if(rayserver->storeStaticPrimitive(vox_prim, NULL, rendID+i))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ LOGMSG("PRIM", "shaveVrayInstance failed to store voxel prmitive on rayserver");
+ delete vox_prim;
+ }
+ }
+
+#else
+ if(rayserver->storeStaticPrimitive(vox_prim, NULL, rendID+i /*rayserver->getNewRenderID()*/))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ LOGMSG("SHAVE", "shaveVrayInstance failed to store voxel prmitive on rayserver");
+ delete vox_prim;
+ }
+#endif
+ }
+ }
+ }
+ else
+ {
+ for(int i = 0; i < num_voxels; i++)
+ {
+ IHairVoxel* voxel = hair()->GetVoxel(i);
+ if(voxel)
+ {
+ shaveVrayMovingVoxelPrim* vox_prim = new shaveVrayMovingVoxelPrim(voxel,vray,this);
+
+ vox_prim->SetTipFade(tipfade());
+ vox_prim->SetUseOwnBSDF(ownbsdf());
+ vox_prim->SetSpecTint(spectint());
+ vox_prim->SetSpecTint2(spectint2());
+ //vox_prim->SetAmbient(ambient());
+#if defined(VRAY30) || defined(VRAY40)
+#if VRAY_DLL_VERSION >= 0x36000
+ int primary_visibility = getPrimaryVisibility();
+#endif
+ if (plugin->useGlobalHairTree && primary_visibility)
+ {
+ vox_prim->storeInGlobalTree(rayserver);
+ _voxprims().push_back(vox_prim);
+ }
+ else
+ {
+ if(rayserver->storeMovingPrimitive(vox_prim, NULL, rendID+i))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ LOGMSG("PRIM", "shaveVrayInstance failed to store voxel prmitive on rayserver");
+ delete vox_prim;
+ }
+ }
+
+#else
+ if(rayserver->storeMovingPrimitive(vox_prim, NULL, rendID+i))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ LOGMSG("PRIM", "shaveVrayInstance failed to store voxel prmitive on rayserver");
+ delete vox_prim;
+ }
+#endif
+ }
+ }
+ }
+#ifdef DEBUG
+#ifdef WIN32
+ assert(_CrtCheckMemory());
+#endif
+#endif
+
+ LOGMSG("SHAVE", "shaveVrayInstance::compileGeometry - OK");
+}
+
+void shaveVrayInstance::clearGeometry(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE", "shaveVrayInstance::clearGeometry");
+
+ /////////// dbg /////////
+ //return;
+ ////////////////////////
+
+ shaveVrayInstanceBase::freeMem();
+#if defined(VRAY30)
+ BaseMeshInstance::clearGeometry(vray);
+#elif defined(VRAY40)
+ BaseInstance::clearGeometry(vray);
+#endif
+
+ //if(stack)
+ //{
+ // delete stack;
+ // stack = NULL;
+ //}
+ LOGMSG("SHAVE", "shaveVrayInstance::clearGeometry - OK");
+}
+
diff --git a/vrayPlug/plugin/shaveVrayInstance.h b/vrayPlug/plugin/shaveVrayInstance.h
new file mode 100644
index 0000000..33288f5
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstance.h
@@ -0,0 +1,147 @@
+#ifndef _HAIR_VRAY_INSTANCE_H_
+#define _HAIR_VRAY_INSTANCE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstance.h
+
+ DESCRIPTION: VRay instance for regular hair
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 30-03-2010
+
+ *>
+ **********************************************************************/
+
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+//own headers
+#include "hairAPIvrayutil.h"
+#include "shaveVrayPlugin.h"
+#include "shaveVrayVoxelPrim.h"
+#include "shaveVrayInstanceBase.h"
+#include "shaveVrayShadeData.h"
+
+#if 0
+class shaveVrayInstance : public shaveVrayInstanceBase {
+public:
+
+ shaveVrayInstance(shaveVrayPlugin *plugin,
+ VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList, const VR::TraceTransform &baseTM, int objectID,
+ const tchar *userAttributes, int primaryVisibility);
+
+ void compileGeometry(VR::VRayRenderer *vray, VR::TraceTransform *tm, double *times, int tmCount);
+ void clearGeometry(VR::VRayRenderer *vray);
+
+
+};
+#endif
+
+
+class shaveVrayInstance :
+#if defined VRAY30
+ public VR::BaseMeshInstance,
+#elif defined(VRAY40)
+ public VR::BaseInstance,
+#endif
+ public shaveVrayInstanceBase{
+public:
+ //shaveVrayPlugin *plugin; //goes to base
+
+
+ shaveVrayInstance(shaveVrayPlugin *plugin,
+ VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#if defined(VRAY30)
+ const VR::TraceTransform &baseTM,
+#elif defined(VRAY40)
+ const VR::Transform &baseTM,
+#endif
+ int objectID,
+ const tchar *userAttributes, int primaryVisibility);
+
+ ~shaveVrayInstance();
+
+#if defined(VRAY30)
+ void compileGeometry(VR::VRayRenderer *vray, VR::TraceTransform *tm, double *times, int tmCount);
+#elif defined(VRAY40)
+ void compileGeometry(VR::VRayRenderer *vray, const VR::Transform *tm, double *times, int tmCount) VRAY_OVERRIDE;
+#endif
+ void clearGeometry(VR::VRayRenderer *vray) VRAY_OVERRIDE;
+
+ //void freeMem();
+ inline bool GetSquirrel() const {return squirrel();}
+ inline bool GetUseOwnBSDF() const { return ownbsdf();}
+ inline const VR::Color& GetSpecTint() const {return spectint();}
+ inline const VR::Color& GetSpecTint2() const {return spectint2();}
+ inline bool GetCameraVisibility() const {return cameraVisibility();}
+ inline bool GetReflVisibility() const {return reflVisibility();}
+ inline bool GetRefrlVisibility() const {return refrVisibility();}
+ inline bool GetLightVisibility() const {return lightVisibility();}
+ inline bool GetGiVisibility() const {return giVisibility();}
+ inline float GetSelfShadow() const {return selfshadow();}
+ inline float GetRecvShadow() const {return recvshadow();}
+
+ inline shaveVrayShadeData* GetShData() const { return shdata();}
+
+protected:
+ ////const member access
+ inline bool tipfade() const {return m_tipfade;}
+ inline bool squirrel() const {return m_squirrel;}
+ inline bool ownbsdf() const {return m_ownbsdf;}
+ inline const VR::Color& spectint() const {return m_spectint;}
+ inline const VR::Color& spectint2() const {return m_spectint2;}
+ inline bool cameraVisibility() const {return m_cameraVisibility;}
+ inline bool lightVisibility() const {return m_lightVisibility;}
+ inline bool reflVisibility() const {return m_reflVisibility;}
+ inline bool refrVisibility() const {return m_refrVisibility;}
+ inline bool giVisibility() const {return m_giVisibility;}
+ inline float selfshadow() const {return m_selfshadow;}
+ inline bool recvshadow() const {return m_recvshadow;}
+ inline shaveVrayShadeData* shdata() const {return m_shdata;}
+
+ ////member access
+ inline bool& _tipfade() {return m_tipfade;}
+ inline bool& _squirrel() {return m_squirrel;}
+ inline bool& _ownbsdf() {return m_ownbsdf;}
+ inline VR::Color& _spectint() {return m_spectint;}
+ inline VR::Color& _spectint2() {return m_spectint2;}
+ inline bool& _cameraVisibility(){return m_cameraVisibility;}
+ inline bool& _reflVisibility() {return m_reflVisibility;}
+ inline bool& _refrVisibility() {return m_refrVisibility;}
+
+ inline bool& _lightVisibility() {return m_lightVisibility;}
+ inline bool& _giVisibility() {return m_giVisibility;}
+ inline float& _selfshadow() {return m_selfshadow;}
+ inline bool& _recvshadow() {return m_recvshadow;}
+ inline shaveVrayShadeData*& _shdata() {return m_shdata;}
+
+
+private:
+ bool m_tipfade;
+ bool m_squirrel;
+ bool m_ownbsdf;
+ VR::Color m_spectint;
+ VR::Color m_spectint2;
+ bool m_cameraVisibility;
+ bool m_reflVisibility;
+ bool m_refrVisibility;
+ bool m_lightVisibility;
+ bool m_giVisibility;
+ float m_selfshadow;
+ bool m_recvshadow;
+
+ shaveVrayShadeData* m_shdata;
+};
+
+
+#endif
diff --git a/vrayPlug/plugin/shaveVrayInstanceBase.cpp b/vrayPlug/plugin/shaveVrayInstanceBase.cpp
new file mode 100644
index 0000000..9678b13
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstanceBase.cpp
@@ -0,0 +1,153 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstanceBase.cpp
+
+ DESCRIPTION: VRay base class for regular and insted hair VRay instance classes
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayInstanceBase.h"
+
+//IHairStack* shaveVrayInstanceBase::stack = NULL;
+
+IHairStack* stack = NULL;
+
+void shaveVrayInstanceBase::loadHair()
+{
+ if(!stack)
+ {
+ //we can not do it in standalone case
+ //shaveVrayIntListParam* dataParam = plugin->GetDataParam();
+ //shaveVrayIntParam* dataSizeParam = plugin->GetDataSizeParam();
+
+ bool dra_as_param = false;
+ bool dra_as_file = false;
+ VR::VRayPluginParameter *dataParam=plugin->paramList->getParam("draData");
+ VR::VRayPluginParameter *dataSizeParam=plugin->paramList->getParam("draSize");
+ if(dataSizeParam && dataParam /*&& dataParam->getCount(0) > 0*/)
+ {
+ LOGMSG("SHAVE", "shaveVrayInstance: importing DRA from memory");
+
+ VR::IntList L = dataParam->getIntList(0);
+
+ //int N = dataParam->getCount(0);
+ int N = L.count();
+ int size = dataSizeParam->getInt(0,0);
+ if(N > 0 && size > 0)
+ {
+ dra_as_param = true;
+
+
+ LOGMSGI("SHAVE", "shaveVrayInstance: DRA data size ", size);
+ LOGMSGI("SHAVE", "shaveVrayInstance: DRA intlist count ", N);
+
+ int extra = 0;
+ int n = size/sizeof(int);
+ if(size > n*sizeof(int))
+ {
+ extra = size - n*sizeof(int);
+ }
+ LOGMSGI("SHAVE", "shaveVrayInstance: (debug) exta bytes ", extra);
+
+ char* data = (char*)malloc(size);
+ int* idata = (int*)data;
+ int chpos = 0;
+ long intsum = 0;
+ for(int oo = 0; oo < N; oo++)
+ {
+ if(oo < n)
+ {
+ //int v = dataParam->getInt(oo,0.0);
+ int v = L[oo];
+ idata[oo] = v;
+ chpos += sizeof(int);
+
+ intsum += v;
+ }
+ else
+ {
+ //int A = dataParam->getInt(oo,0.0);
+ int A = L[oo];
+ char* AA = (char*)(&A);
+ for(int j = 0; j < extra; j++)
+ {
+ data[chpos+j] = AA[j];
+ }
+
+ intsum += A;
+ }
+ }
+ ///// checksum //
+ int sum = 0;
+ for(int oo = 0; oo < size; oo++)
+ {
+ sum += (unsigned char)data[oo];
+ }
+ LOGMSGI("SHAVE", "shaveVrayInstance: (debug) checksum ", (int)sum);
+ LOGMSGI("SHAVE", "shaveVrayInstance: (debug) intsum ", (int)intsum);
+
+ stack = LoadHair((void*)data,(long)size);
+ }
+
+ }
+
+ if(!dra_as_param && !shaveVrayPlugin::draFile.empty())
+ {
+ dra_as_file = true;
+ LOGMSG("SHAVE", "shaveVrayInstance: importing DRA from file.");
+ stack = LoadHair((char*)shaveVrayPlugin::draFile.ptr());
+ }
+
+ if(!dra_as_param && !dra_as_file)
+ {
+ LOGMSG("SHAVE", "shaveVrayInstance: no DRA source specified.");
+ }
+ }
+ if(!hair() && stack)
+ {
+ if(stack)
+ {
+ try
+ {
+ _hair() = stack->GetHairNodeByID(stackid(),GetSquirrel());
+ }
+ catch(...)
+ {
+ LOGMSG("SHAVE", "shaveVrayInstance: an exception occured when accessing DRA.");
+ }
+ if(!hair())
+ LOGMSGI("SHAVE", "shaveVrayInstance: can not create Hair node (id)",stackid());
+ }
+ else
+ LOGMSG("SHAVE", "shaveVrayInstance::compileGeometry NULL stack.");
+ }
+}
+
+void shaveVrayInstanceBase::freeMem()
+{
+ //free primitieves here
+ for(unsigned int i = 0; i < (unsigned int)voxprims().size(); i++)
+ if(voxprim(i))
+ {
+ delete voxprim(i);
+ _voxprim(i) = NULL;
+ }
+ _voxprims().clear();
+
+
+ if(stack)
+ {
+ delete stack;
+ stack = NULL;
+ }
+}
+
diff --git a/vrayPlug/plugin/shaveVrayInstanceBase.h b/vrayPlug/plugin/shaveVrayInstanceBase.h
new file mode 100644
index 0000000..a90b374
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstanceBase.h
@@ -0,0 +1,105 @@
+#ifndef _HAIR_VRAY_INSTANCE_base_H_
+#define _HAIR_VRAY_INSTANCE_base_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstanceBase.h
+
+ DESCRIPTION: VRay base class for regular and insted hair VRay instance classes
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 11-05-2010
+
+ *>
+ **********************************************************************/
+
+//std
+#include <vector>
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+//own headers
+#include "hairAPIvrayutil.h"
+#include "shaveVrayPlugin.h"
+#include "shaveVrayVoxelPrimBase.h"
+
+//hair stack
+//we need 2 stacks for instanced and regular hair,
+//so it goes to shaveVrayInstance members
+extern IHairStack* stack;
+
+class shaveVrayInstanceBase /*: public VR::BaseMeshInstance*/ {
+public:
+ shaveVrayPlugin *plugin;
+
+ //static IHairStack* stack;
+
+ //shaveVrayPlugin *plugin;
+
+ //shaveVrayInstanceBase(
+ // shaveVrayPlugin *vplugin ,
+ // VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ // VR::VolumetricInterface *volume, VR::LightList *lightList, const VR::TraceTransform &baseTM, int objectID,
+ // const tchar *userAttributes, int primaryVisibility)
+ // :
+ // plugin(vplugin),
+ // VR::BaseMeshInstance(vplugin, vplugin, mtl, bsdf,
+ // renderID, volume, lightList,
+ // baseTM, objectID, userAttributes,
+ // primaryVisibility)
+ //{
+ // _hair() = NULL;
+ // _stackid() = plugin->GetStackIndex();
+ //}
+ shaveVrayInstanceBase(shaveVrayPlugin *plug){plugin = plug;}
+ virtual ~shaveVrayInstanceBase() {}
+
+ void loadHair();
+ void freeMem();
+
+ int GetNumFacesPerInst() const {return numFacesPerInst();}
+ int GetNumUVSets() const {return numUVSets();}
+ const VR::Vector& GetUV(int i) const {return uv(i);}
+
+ virtual bool GetSquirrel() const = 0;
+
+protected:
+ //const member access
+ inline const std::vector<shaveVrayVoxelPrimBase*>& voxprims() const {return m_voxprims;}
+ inline shaveVrayVoxelPrimBase* voxprim(unsigned int i) const {return m_voxprims[i];}
+ inline int stackid() const {return m_stackid;}
+ inline int numFacesPerInst() const {return m_numFacesPerInst;}
+ inline int numUVSets() const {return m_numUVSets;}
+ inline const VR::VectorList& uvs()const {return m_uvs;}
+ inline const VR::Vector& uv(int i)const {return m_uvs[i];}
+ inline IHairNode* hair() const {return m_hair;}
+
+ //member access
+ inline std::vector<shaveVrayVoxelPrimBase*>& _voxprims() {return m_voxprims;}
+ inline shaveVrayVoxelPrimBase*& _voxprim(unsigned int i){return m_voxprims[i];}
+ inline int& _stackid() {return m_stackid;}
+ inline int& _numFacesPerInst() {return m_numFacesPerInst;}
+ inline int& _numUVSets() {return m_numUVSets;}
+ inline VR::VectorList& _uvs() {return m_uvs;}
+ inline IHairNode*& _hair() {return m_hair;}
+
+private:
+ //moving or static primiteves
+ std::vector<shaveVrayVoxelPrimBase*> m_voxprims;
+
+ int m_stackid;
+ int m_numFacesPerInst;
+ int m_numUVSets;
+ VR::VectorList m_uvs;
+ IHairNode* m_hair;
+};
+
+
+#endif //end of_HAIR_VRAY_INSTANCE_base_H_
diff --git a/vrayPlug/plugin/shaveVrayInstanceI.cpp b/vrayPlug/plugin/shaveVrayInstanceI.cpp
new file mode 100644
index 0000000..bc85015
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstanceI.cpp
@@ -0,0 +1,162 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstanceI.cpp
+
+ DESCRIPTION: VRay instnace for instanced hair
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayInstanceI.h"
+#include "shaveVrayMovingTriVoxelPrim.h"
+#include "shaveVrayStaticTriVoxelPrim.h"
+
+
+
+shaveVrayInstanceI::shaveVrayInstanceI(
+ shaveVrayPlugin *vplugin,
+ VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#if defined(VRAY30)
+ const VR::TraceTransform &baseTM,
+#elif defined(VRAY40)
+ const VR::Transform &baseTM,
+#endif
+ int objectID,
+ const tchar *userAttributes, int primaryVisibility)
+ :
+#if defined(VRAY30)
+ VR::BaseMeshInstance(vplugin, vplugin, mtl, bsdf, renderID, volume, lightList, baseTM, objectID, userAttributes, primaryVisibility),
+#elif defined(VRAY40)
+ VR::BaseInstance(vplugin, mtl, bsdf, renderID, volume, lightList, baseTM, objectID, userAttributes, primaryVisibility),
+#endif
+ shaveVrayInstanceBase(vplugin)
+{
+ _hair() = NULL;
+ _stackid() = plugin->GetStackIndex();
+ _numFacesPerInst() = plugin->GetNumFacesPerInst();
+ _numUVSets() = plugin->GetNumUVSets();
+
+
+ //shaveVrayVectorListParam* uvsParam = vplugin->GetUVparam();
+ VR::VRayPluginParameter *uvsParam=plugin->paramList->getParam("uvs");
+ if(uvsParam)
+ {
+ _uvs() = uvsParam->getVectorList(0);
+
+ //int nuvs = uvsParam->getCount(0);
+ //_uvs() = VR::VectorList(nuvs);
+ //for(int i = 0; i < nuvs; i++)
+ //{
+ // VR::Vector v = uvsParam->operator[](i);
+ // _uvs()[i] = v;
+ //}
+ }
+}
+
+
+void shaveVrayInstanceI::compileGeometry(
+ VR::VRayRenderer *vray,
+#if defined(VRAY30)
+ VR::TraceTransform *tm,
+#elif defined(VRAY40)
+ const VR::Transform *tm,
+#endif
+ double *times, int tmCount)
+{
+ LOGMSG("SHAVE", "shaveVrayInstanceI::compileGeometry");
+ LOGMSGI("SHAVE", "id",stackid());
+
+ loadHair();
+
+ if(!hair())
+ return;
+
+#if defined(VRAY30)
+ BaseMeshInstance::compileGeometry(vray, tm, times, tmCount);
+#elif defined(VRAY40)
+ BaseInstance::compileGeometry(vray, tm, times, tmCount);
+#endif
+
+ int num_voxels = hair()->GetNumVoxels();
+ VR::RayServerInterface *rayserver = vray->getRayServer();
+ int rendID = rayserver->getNewRenderIDArray(num_voxels);
+
+ const VR::VRaySequenceData& sdata = vray->getSequenceData();
+ bool blurOn = sdata.params.moblur.on != 0;
+ //tm is not animated
+ if ( !blurOn )
+ {
+ for(int i = 0; i < num_voxels; i++)
+ {
+ IHairVoxel* voxel = hair()->GetVoxel(i);
+ if(voxel)
+ {
+ shaveVrayStaticTriVoxelPrim* vox_prim = new shaveVrayStaticTriVoxelPrim(voxel,vray,this);
+
+
+ if(rayserver->storeStaticPrimitive(vox_prim, NULL, rendID+i ))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ delete vox_prim;
+ LOGMSG("SHAVE", "shaveVrayInstanceI failed to store voxel prmitive on rayserver");
+
+ }
+ }
+ }
+ }
+ else
+ {
+ for(int i = 0; i < num_voxels; i++)
+ {
+ IHairVoxel* voxel = hair()->GetVoxel(i);
+ if(voxel)
+ {
+ shaveVrayMovingTriVoxelPrim* vox_prim = new shaveVrayMovingTriVoxelPrim(voxel,vray,this);
+
+
+ if(rayserver->storeMovingPrimitive(vox_prim, NULL, rendID+i))
+ _voxprims().push_back(vox_prim);
+ else
+ {
+ delete vox_prim;
+ LOGMSG("SHAVE", "shaveVrayInstanceI failed to store voxel prmitive on rayserver");
+
+ }
+ }
+ }
+ }
+ LOGMSG("SHAVE", "shaveVrayInstanceI::compileGeometry - OK");
+}
+
+void shaveVrayInstanceI::clearGeometry(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE", "shaveVrayInstanceI::clearGeometry");
+
+ shaveVrayInstanceBase::freeMem();
+#if defined(VRAY30)
+ BaseMeshInstance::clearGeometry(vray);
+#elif defined(VRAY40)
+ BaseInstance::clearGeometry(vray);
+#endif
+
+ //if(stack)
+ //{
+ // delete stack;
+ // stack = NULL;
+ //}
+ LOGMSG("SHAVE", "shaveVrayInstanceI::clearGeometry - OK");
+}
+
+
+
+
diff --git a/vrayPlug/plugin/shaveVrayInstanceI.h b/vrayPlug/plugin/shaveVrayInstanceI.h
new file mode 100644
index 0000000..2d3d614
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayInstanceI.h
@@ -0,0 +1,93 @@
+#ifndef _HAIR_VRAY_INSTANCE_instanced_H_
+#define _HAIR_VRAY_INSTANCE_instanced_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayInstanceI.h
+
+ DESCRIPTION: VRay instance for instnaced hair
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 11-05-2010
+
+ *>
+ **********************************************************************/
+
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+//own headers
+#include "hairAPIvrayutil.h"
+#include "shaveVrayPlugin.h"
+#include "shaveVrayVoxelPrim.h"
+#include "shaveVrayInstanceBase.h"
+
+
+class shaveVrayInstanceI :
+#if defined VRAY30
+ public VR::BaseMeshInstance,
+#elif defined(VRAY40)
+ public VR::BaseInstance,
+#endif
+ public shaveVrayInstanceBase{
+public:
+ //shaveVrayPlugin *plugin; //goes to base
+
+
+ shaveVrayInstanceI(shaveVrayPlugin *plugin,
+ VR::MaterialInterface *mtl, VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#if defined(VRAY30)
+ const VR::TraceTransform &baseTM,
+#elif defined(VRAY40)
+ const VR::Transform &baseTM,
+#endif
+ int objectID,
+ const tchar *userAttributes, int primaryVisibility);
+
+ void compileGeometry(VR::VRayRenderer *vray,
+#if defined(VRAY30)
+ VR::TraceTransform *tm,
+#elif defined(VRAY40)
+ const VR::Transform *tm,
+#endif
+ double *times, int tmCount) VRAY_OVERRIDE;
+ void clearGeometry(VR::VRayRenderer *vray) VRAY_OVERRIDE;
+
+ //void freeMem();
+
+ //VR::Transform GetItm0() const {return itm[0];}
+
+ bool GetSquirrel() const {return false;}
+
+protected:
+ ////const member access
+ //inline const std::vector<shaveVrayVoxelPrim*>& voxprims() const {return m_voxprims;}
+ //inline shaveVrayVoxelPrim* voxprim(unsigned int i) const {return m_voxprims[i];}
+ //inline int stackid() const {return m_stackid;}
+ //inline IHairNode* hair() const {return m_hair;}
+
+ ////member access
+ //inline std::vector<shaveVrayVoxelPrim*>& _voxprims() {return m_voxprims;}
+ //inline shaveVrayVoxelPrim*& _voxprim(unsigned int i){return m_voxprims[i];}
+ //inline int& _stackid() {return m_stackid;}
+ //inline IHairNode*& _hair() {return m_hair;}
+
+private:
+ ////moving or static primiteves
+ //std::vector<shaveVrayVoxelPrim*> m_voxprims;
+
+ //int m_stackid;
+ //IHairNode* m_hair;
+};
+
+
+
+#endif //end of_HAIR_VRAY_INSTANCE_instanced_H_
diff --git a/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp
new file mode 100644
index 0000000..b9b3686
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.cpp
@@ -0,0 +1,353 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayMovingTriVoxelPrim.cpp -- iplementation file
+
+ DESCRIPTION: Static (non motion blurred) instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayMovingTriVoxelPrim.h"
+#include "shaveVrayInstanceI.h"
+#include "misc_ray.h"
+#include "vray3_compat.h"
+
+shaveVrayMovingTriVoxelPrim::shaveVrayMovingTriVoxelPrim(
+ IHairVoxel* vox,
+ VR::VRayCore *vray,
+ shaveVrayInstanceI *inst):
+ shaveVrayTriVoxelPrim(vox,vray,inst)
+{
+ _firstid() = -1;
+ _tris() = NULL;
+ //_numblur() = 2;
+
+ if(voxel())
+ {
+ VERT pmin;
+ VERT pmax;
+ voxel()->GetBbox(pmin,pmax);
+
+ _bbox().init();//MovingBox
+ _bbox().b[0].pmin.x = pmin.x;
+ _bbox().b[0].pmin.y = pmin.y;
+ _bbox().b[0].pmin.z = pmin.z;
+
+ _bbox().b[0].pmax.x = pmax.x;
+ _bbox().b[0].pmax.y = pmax.y;
+ _bbox().b[0].pmax.z = pmax.z;
+
+ VR::Vector scnoffs = VR::toVector(sceneOffset());
+ _bbox().b[0].pmin -= scnoffs;
+ _bbox().b[0].pmax -= scnoffs;
+
+ //calc speed box
+ const HairType& hair = voxel()->GetHair();
+ int nv = hair.GetNumVerts();
+ for(int i = 0; i < nv; i++)
+ {
+ float x, y, z;
+ hair.GetVelocity(i,x,y,z);
+
+ _bbox().b[1].pmin.x = bbox().b[1].pmin.x > x ? x : bbox().b[1].pmin.x;
+ _bbox().b[1].pmin.y = bbox().b[1].pmin.y > y ? y : bbox().b[1].pmin.y;
+ _bbox().b[1].pmin.z = bbox().b[1].pmin.z > z ? z : bbox().b[1].pmin.z;
+
+ _bbox().b[1].pmax.x = bbox().b[1].pmax.x < x ? x : bbox().b[1].pmax.x;
+ _bbox().b[1].pmax.y = bbox().b[1].pmax.y < y ? y : bbox().b[1].pmax.y;
+ _bbox().b[1].pmax.z = bbox().b[1].pmax.z < z ? z : bbox().b[1].pmax.z;
+ }
+ _bbox().t[0] = 0.0f;
+ _bbox().t[1] = 1.0f;
+
+ /*DebugPrint("[%f %f %f][%f %f %f]\n",
+ pmin.x, pmin.y, pmin.z,
+ pmax.x, pmax.y, pmax.z);*/
+ }
+}
+
+shaveVrayMovingTriVoxelPrim::~shaveVrayMovingTriVoxelPrim()
+{
+}
+
+/*
+| from MovingPrimitive
+*/
+void shaveVrayMovingTriVoxelPrim::getBBox (VR::MovingBox &box)
+{
+ //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::getBBox ");
+
+ box = bbox();
+}
+
+/*
+| from StaticPrimitive
+*/
+bool shaveVrayMovingTriVoxelPrim::splittable ()
+{
+ //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::splitable\n");
+
+ return true;
+}
+
+/*
+| from StaticPrimitive
+*/
+void shaveVrayMovingTriVoxelPrim::split (int dim, VR::real middle, VR::MovingBox &bLeft, VR::MovingBox &bRight)
+{
+ //DebugPrint("PRIM> shaveVrayMovingTriVoxelPrim::split [%i %f]\n",dim,middle);
+
+ VR::MovingBox bbox;
+ getBBox(bbox);
+ bbox.split(dim, middle, bLeft, bRight);
+}
+/*
+| from StaticPrimitive
+*/
+int shaveVrayMovingTriVoxelPrim::expandable()
+{
+ return true;
+}
+/*
+| from StaticPrimitive
+*/
+int shaveVrayMovingTriVoxelPrim::expand (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex)
+{
+ const HairType& hair = voxel()->GetHair();
+ int numFaces = hair.GetNumFaces();
+ int numVerts = hair.GetNumVerts();
+
+ if(numFaces == 0)
+ return 0;
+
+ //int numblur_prims = numblur() - 1;
+ //float step = 1.0f/(float)numblur_prims;
+
+ if(firstid() == -1)
+ _firstid() = raycaster->getNewRenderIDArray(numFaces/**numblur_prims*/);
+
+
+ _normals().resize(numVerts);
+ for(int i = 0; i < numVerts; i++)
+ {
+ _normal(i) = VR::Vector(0.0f,0.0f,0.0f);
+ }
+
+ VR::Vector p0[3];
+ VR::Vector p1[3];
+ VR::Vector v[3];
+ float t0 = 0.0f;
+ float t1 = 0.99f;
+ float dt = t1 - t0;
+ _tris() = new VR::MovingTriangle[numFaces];
+ VR::Vector scnoffs=VR::toVector(sceneOffset());
+ for(int i = 0; i < numFaces; i++)
+ {
+ int fs;
+ int fe;
+ int k = 0;
+ //int k = 2;
+ hair.GetFace(i,fs,fe);
+ int df = fe - fs; //we expect triangular mesh
+ if(df != 3)
+ {
+ LOGMSGI("PRIM", "triangular face is expected, vertex count:",df);
+ continue;
+ }
+ for(int j = fs; j < fe; j++)
+ {
+ int vert_idx = hair.GetFaceVert(j);
+ //hair.GetVert (vert_idx,_tri(i).p[k].x,_tri(i).p[k].y,_tri(i).p[k].z);
+ //hair.GetVelocity(vert_idx,_tri(i).d[k].x,_tri(i).d[k].y,_tri(i).d[k].z);
+ //_tri(i).d[k] = VR::Vector();
+ //_tri(i).p[k] -= sceneOffset();
+
+ hair.GetVert (vert_idx, p0[k].x, p0[k].y, p0[k].z);
+ hair.GetVelocity(vert_idx, v[k].x, v[k].y, v[k].z);
+ p0[k] -= scnoffs;
+ p1[k] = p0[k] + v[k]*dt;
+
+ k++;
+ }
+ //_tri(i).t[0] = 0.0f;
+ //_tri(i).t[1] = 1.0f;
+ _tri(i).init(p0,p1 /*v*/ /*p0*/,t0,t1);
+ raycaster->insertPrimitive(threadIndex, &_tri(i), static_cast<GeometryGenerator*>(this), i + firstid());
+
+ // pre-compute normals
+ int i0 = hair.GetFaceVert(fs);
+ int i1 = hair.GetFaceVert(fs+1);
+ int i2 = hair.GetFaceVert(fs+2);
+ VR::Vector v0;
+ VR::Vector v1;
+ VR::Vector v2;
+ hair.GetVert(i0,v0.x,v0.y,v0.z);
+ hair.GetVert(i1,v1.x,v1.y,v1.z);
+ hair.GetVert(i2,v2.x,v2.y,v2.z);
+
+ VR::Vector e0 = v1-v0;
+ VR::Vector e1 = v2-v0;
+
+ VR::Vector fn = -normalize(e0^e1);
+
+ _normal(i0) += fn;
+ _normal(i1) += fn;
+ _normal(i2) += fn;
+ }
+
+ for(int i = 0; i < numVerts; i++)
+ {
+ _normal(i) = normalize(normal(i));
+ }
+
+#ifdef _DEBUG
+#ifdef WIN32
+ assert(_CrtCheckMemory());
+#endif
+#endif
+ return numFaces*sizeof(VR::MovingTriangle);
+}
+
+/*
+| from StaticPrimitive
+*/
+int shaveVrayMovingTriVoxelPrim::collapse (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex)
+{
+ const HairType& hair = voxel()->GetHair();
+ int numFaces = hair.GetNumFaces();
+
+ if(numFaces == 0)
+ return 0;
+
+ if(tris())
+ {
+ for (int i=0; i < numFaces; i++)
+ raycaster->removePrimitive(threadIndex, &_tri(i));
+
+ delete[] tris();
+ _tris() = NULL;
+ }
+ _normals().clear();
+
+ return numFaces*sizeof(VR::MovingTriangle);
+}
+/*
+| from GeometryGenerator
+*/
+void shaveVrayMovingTriVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd)
+{
+ VR::IntersectionData &isData=*((VR::IntersectionData*) isd);
+ VR::RSIntersection &is=rsray.is;
+
+ assert(PRIM_TYPE_MOVING_TRIANGLE == is.primitive->type());
+
+ shaveVrayMovingTriVoxelPrim* owner =(shaveVrayMovingTriVoxelPrim*) (is.primitive->owner);
+ assert(owner == this);
+
+ VR::MovingTriangle* T = (VR::MovingTriangle*)is.primitive;
+
+ const HairType& hair = voxel()->GetHair();
+
+ isData.primitive=is.primitive;
+ isData.skipTag =is.skipTag;
+ isData.faceIndex= T->ownerIndex - firstid();
+#ifdef OWN_SHADEABLE_FOR_TRI
+ isData.sb = shade();
+#else
+ isData.sb = shdata();
+#endif
+ isData.sd = shdata();
+ isData.si = NULL; //shinst();
+ isData.volume=NULL;
+
+ isData.bary=VR::toShadeVec(is.bary);
+ isData.wpointCoeff=is.t;
+
+ isData.faceBase=VR::toShadeVec(T->p[0]);
+ isData.faceEdge0=VR::toShadeVec(T->p[1]);
+ isData.faceEdge1=VR::toShadeVec(T->p[2]);
+ isData.faceEdge0-=isData.faceBase;
+ isData.faceEdge1-=isData.faceBase;
+
+ isData.gnormal= -normalize(isData.faceEdge0^isData.faceEdge1); //VR::Vector();
+#if 0
+ isData.normal = isData.gnormal;//T->getNormal(rsray);
+#else
+ int fs;
+ int fe;
+ hair.GetFace(isData.faceIndex,fs,fe);
+
+ int v0 = hair.GetFaceVert(fs);
+ int v1 = hair.GetFaceVert(fs+1);
+ int v2 = hair.GetFaceVert(fs+2);
+
+ VR::ShadeVec n0 = VR::toShadeVec(normal(v0));
+ VR::ShadeVec n1 = VR::toShadeVec(normal(v1));
+ VR::ShadeVec n2 = VR::toShadeVec(normal(v2));
+ VR::ShadeVec N = is.bary.x*n0 + is.bary.y*n1 + is.bary.z*n2;
+ isData.normal = normalize(N);
+#endif
+
+ isData.wpoint=VR::toShadeVec(rsray.p) + VR::toShadeVec(rsray.dir)*is.t;
+
+ // We don't have any meaningful data here
+ isData.surfaceProps = NULL; // sfprops();
+}
+
+
+#if defined(VRAY30)
+
+void shaveVrayMovingTriVoxelPrim::setIntersectionData(const VR::RayBunchParams& params,
+ VR::PrimitiveIntersections& result,
+ const RAY_IDX* idxs,
+ size_t count)
+{
+ for(size_t ii=0; ii<count; ++ii) {
+ const RAY_IDX idx=idxs[ii];
+
+ VR::MovingTriangle* T = (VR::MovingTriangle*)(result.primitives()[idx]);
+
+ shaveVrayMovingTriVoxelPrim* owner = static_cast<shaveVrayMovingTriVoxelPrim*>(result.primitives()[idx]->owner);
+ assert(owner == this);
+
+ const HairType& hair = voxel()->GetHair();
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ result.faceIndices()[idx] = T->ownerIndex - firstid();
+
+ result.skipTags()[idx] = params.parentSkipTags()[idx];
+
+ //VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment
+ double dist = result.rayDistances()[ idx ];
+ double isectPtX = params.origins(0)[ idx ] + params.dirs(0)[ idx ] * dist;
+ double isectPtY = params.origins(1)[ idx ] + params.dirs(1)[ idx ] * dist;
+ double isectPtZ = params.origins(2)[ idx ] + params.dirs(2)[ idx ] * dist;
+
+ *(result.isectPoints(0) + idx) = isectPtX;
+ *(result.isectPoints(1) + idx) = isectPtY;
+ *(result.isectPoints(2) + idx) = isectPtZ;
+
+ VR::Vector gn = T->getGNormal(params, result, idx);
+ result.geomNormals(0)[idx] = gn[0];
+ result.geomNormals(1)[idx] = gn[1];
+ result.geomNormals(2)[idx] = gn[2];
+
+ for(int d=0; d<3; d++)
+ result.facesBase(d)[idx]=T->p[0][d];
+ for(int d=0; d<3; d++)
+ result.facesEdge0(d)[idx]=T->p[1][d]-T->p[0][d];
+ for(int d=0; d<3; d++)
+ result.facesEdge1(d)[idx]=T->p[2][d]-T->p[0][d];
+ }
+}
+
+#endif // VRAY30
diff --git a/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.h b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.h
new file mode 100644
index 0000000..e3bc821
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayMovingTriVoxelPrim.h
@@ -0,0 +1,108 @@
+#ifndef _HAIR_VR_MOVING_tri_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_MOVING_tri_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayMovingTriVoxelPrim.h
+
+ DESCRIPTION: Moving (motion blurred) hair instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayTriVoxelPrim.h"
+#include "hairprimitives.h"
+
+#include <vector>
+
+
+class shaveVrayMovingTriVoxelPrim : public shaveVrayTriVoxelPrim,
+ public VR::MovingPrimitive {
+public:
+ shaveVrayMovingTriVoxelPrim(IHairVoxel* voxel, VR::VRayCore *vray, shaveVrayInstanceI* inst);
+ virtual ~shaveVrayMovingTriVoxelPrim();
+
+ /*
+ | from MovingPrimitive
+ */
+ // Return the bounding box of this primitive.
+ void getBBox (VR::MovingBox &bbox);
+
+ //Return true if the primitive is splittable.
+ bool splittable ();
+
+ //Return the bounding boxes of the primitive with respect to a given plane.
+ void split (int dim, VR::real middle, VR::MovingBox &bLeft, VR::MovingBox &bRight);
+
+ //Return true here
+ int expandable();
+
+ //Expand the primitive into other sub-primitives.
+ int expand (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex);
+
+ //Collapse the primitive.
+ int collapse (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex);
+
+ /*
+ | from GeometryGenerator
+ */
+ void setIntersectionData(VR::RSRay &rsray, void *isData);
+
+#if defined VRAY30
+ void setIntersectionData(const VR::RayBunchParams& params,
+ VR::PrimitiveIntersections& result,
+ const RAY_IDX* idxs,
+ size_t count);
+#endif
+
+#ifdef OWN_SHADEABLE_FOR_TRI
+ VR::Shadeable* getShadeable() { return shade(); }
+#else
+ VR::Shadeable* getShadeable() { return shdata(); }
+#endif
+ VR::VRayShadeInstance* getExtShadeData() { return NULL; }
+ VR::VRayShadeData* getExtTexMapping() { return shdata(); }
+ VR::VRayVolume* getVolumeShader() { return NULL; }
+ VR::VRaySurfaceProperties* getExtSurfaceProperties() { return NULL; }
+
+protected:
+
+ //const member access
+ inline const VR::MovingBox& bbox() const {return m_bbox;}
+ inline const std::vector<VR::Vector>& normals() const {return m_normals;}
+ inline const VR::Vector& normal(int i) const {return m_normals[i];}
+ inline const VR::MovingTriangle& tri(int i) const {return m_tris[i];}
+ inline VR::MovingTriangle* tris() const {return m_tris;}
+ inline int firstid() const {return m_firstid;}
+ //inline int numblur() const {return m_numblur;}
+
+ //member access
+ inline VR::MovingBox& _bbox() {return m_bbox;}
+ inline std::vector<VR::Vector>& _normals() {return m_normals;}
+ inline VR::Vector& _normal(int i) {return m_normals[i];}
+ inline VR::MovingTriangle& _tri(int i) {return m_tris[i];}
+ inline VR::MovingTriangle*& _tris() {return m_tris;}
+ inline int& _firstid() {return m_firstid;}
+ //inline int& _numblur() {return m_numblur;}
+
+
+private:
+
+ VR::MovingBox m_bbox;
+ int m_firstid;
+ //int m_numblur; //it is just 2
+ VR::MovingTriangle* m_tris;
+ std::vector<VR::Vector> m_normals;
+
+};
+
+
+#endif //end of_HAIR_VR_MOVING_tri_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/shaveVrayMovingVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayMovingVoxelPrim.cpp
new file mode 100644
index 0000000..35e528d
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayMovingVoxelPrim.cpp
@@ -0,0 +1,948 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayMovingVoxelPrim.cpp -- iplementation file
+
+ DESCRIPTION: Motion blurred hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 04-09-2008
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayMovingVoxelPrim.h"
+#include "shaveVraySharedFunctions.h"
+
+#if defined(VRAY30) || defined(VRAY40)
+#include "shaveVrayInstance.h"
+using namespace VUtils;
+#endif
+
+
+shaveVrayMovingVoxelPrim::shaveVrayMovingVoxelPrim(IHairVoxel* vox,
+ VR::VRayCore *vray,
+ shaveVrayInstance *inst)
+ :shaveVrayVoxelPrim(vox,vray,inst)
+#if defined(VRAY30) || defined(VRAY40)
+ , movingHairTree(NULL)
+#endif
+{
+ _firstid() = -1;
+ _numblur() = 2;
+ _pts() = NULL;
+ _dpts() = NULL;
+ _uns() = NULL;
+ _duns() = NULL;
+ _vns() = NULL;
+ _dvns() = NULL;
+ _strands() = NULL;
+
+#if defined(VRAY30) || defined(VRAY40)
+ minLeaf=0.0f;
+ leafCoeff=1.0f;
+ maxDepth=80;
+
+ const VRaySequenceData &sdata=vray->getSequenceData();
+ const VRayFrameData &fdata=vray->getFrameData();
+
+ threadman=sdata.threadManager;
+ prog=sdata.progress;
+
+#if VRAY_DLL_VERSION < 0x36000
+ tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth);
+#else
+ tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth, fdata.worldToCam, fdata.projType, fdata.zoomFractor, fdata.devAspect);
+#endif
+ tessParams.setSubdivThresh(inst->plugin->edgeLen);
+#endif
+ if(voxel())
+ {
+ VERT pmin;
+ VERT pmax;
+ voxel()->GetBbox(pmin,pmax);
+
+ _bbox().init();//MovingBox
+#if defined(VRAY30)
+ _bbox().b[0].pmin.x = pmin.x;
+ _bbox().b[0].pmin.y = pmin.y;
+ _bbox().b[0].pmin.z = pmin.z;
+
+ _bbox().b[0].pmax.x = pmax.x;
+ _bbox().b[0].pmax.y = pmax.y;
+ _bbox().b[0].pmax.z = pmax.z;
+
+ _bbox().b[0].pmin -= sceneOffset();
+ _bbox().b[0].pmax -= sceneOffset();
+#else
+ TracePoint tpmin(pmin.x, pmin.y, pmin.z);
+ TracePoint tpmax(pmax.x, pmax.y, pmax.z);
+ tpmin -= sceneOffset();
+ tpmax -= sceneOffset();
+ _bbox().b[0].pmin = tpmin.toVector();
+ _bbox().b[0].pmax = tpmax.toVector();
+#endif
+
+ //calc speed box
+ const HairType& hair = voxel()->GetHair();
+ int nv = hair.GetNumVerts();
+ for(int i = 0; i < nv; i++)
+ {
+ float x, y, z;
+ hair.GetVelocity(i,x,y,z);
+
+ _bbox().b[1].pmin.x = bbox().b[1].pmin.x > x ? x : bbox().b[1].pmin.x;
+ _bbox().b[1].pmin.y = bbox().b[1].pmin.y > y ? y : bbox().b[1].pmin.y;
+ _bbox().b[1].pmin.z = bbox().b[1].pmin.z > z ? z : bbox().b[1].pmin.z;
+
+ _bbox().b[1].pmax.x = bbox().b[1].pmax.x < x ? x : bbox().b[1].pmax.x;
+ _bbox().b[1].pmax.y = bbox().b[1].pmax.y < y ? y : bbox().b[1].pmax.y;
+ _bbox().b[1].pmax.z = bbox().b[1].pmax.z < z ? z : bbox().b[1].pmax.z;
+ }
+ _bbox().t[0] = 0.0f;
+ _bbox().t[1] = 1.0f;
+
+ /*DebugPrint("[%f %f %f][%f %f %f]\n",
+ pmin.x, pmin.y, pmin.z,
+ pmax.x, pmax.y, pmax.z);*/
+ }
+
+ _pool_Vector().init(sizeof(VR::Vector)*2*3*numknots(), 1000);
+}
+
+shaveVrayMovingVoxelPrim::~shaveVrayMovingVoxelPrim()
+{
+ //these should be released in ::collapse()
+ //but we add this code here in any case
+ if(pts())
+ delete [] pts();
+
+ if(dpts())
+ delete [] dpts();
+
+ if(uns())
+ delete [] uns();
+
+ if(duns())
+ delete [] duns();
+
+ if(vns())
+ delete [] vns();
+
+ if(dvns())
+ delete [] dvns();
+
+#if defined(VRAY30) || defined(VRAY40)
+ delete movingHairTree;
+#endif
+}
+
+/*
+| from MovingPrimitive
+*/
+void shaveVrayMovingVoxelPrim::getBBox (VR::MovingBox &box)
+{
+ //DebugPrint("PRIM> shaveVrayMovingVoxelPrim::getBBox ");
+
+ box = bbox();
+}
+
+/*
+| from MovingPrimitive
+*/
+bool shaveVrayMovingVoxelPrim::splittable ()
+{
+ //DebugPrint("PRIM> shaveVrayMovingVoxelPrim::splitable\n");
+
+ return true;
+}
+
+/*
+| from MovingPrimitive
+*/
+void shaveVrayMovingVoxelPrim::split (int dim, VR::real middle, VR::MovingBox &bLeft, VR::MovingBox &bRight)
+{
+ //DebugPrint("PRIM> shaveVrayMovingVoxelPrim::split [%i %f]\n",dim,middle);
+
+ VR::MovingBox bbox;
+ getBBox(bbox);
+ bbox.split(dim, middle, bLeft, bRight);
+}
+/*
+| from MovingPrimitive
+*/
+int shaveVrayMovingVoxelPrim::expandable()
+{
+ return true;
+}
+/*
+| from MovingHairGenerator
+*/
+int shaveVrayMovingVoxelPrim::getNumSides() const
+{
+ return 4;
+}
+
+/*
+| from MovingHairGenerator
+*/
+int shaveVrayMovingVoxelPrim::getNumKnots()
+{
+ return numknots();
+}
+/*
+| from MovingHairGenerator
+*/
+void shaveVrayMovingVoxelPrim::getSidesUV(float *&uc, float *&vc)
+{
+ uc = _puc();
+ vc = _pvc();
+}
+/*
+| from MovingHairGenerator
+*/
+void shaveVrayMovingVoxelPrim::getSidesUV(const float *&uc, const float *&vc) const
+{
+ uc = puc();
+ vc = pvc();
+}
+/*
+| from MovingHairGenerator
+*/
+int shaveVrayMovingVoxelPrim::getFlatNormal() const
+{
+ return true;
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getRadius()
+{
+ return 1.0f; //not sure
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getLength()
+{
+ return 100.f; //not sure
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getTaper()
+{
+ return 0.0f; //not sure
+}
+/*
+| from MovingHairGenerator
+*/
+VR::Vector shaveVrayMovingVoxelPrim::getGravity()
+{
+ return VR::Vector(0.0f, 0.0f, 0.0f); //not sure
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getLengthRand()
+{
+ return 0.0f;
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getRadiusRand()
+{
+ return 0.0f;
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getGravityRand()
+{
+ return 0.0f;
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getDirRand()
+{
+ return 0.0f;
+}
+/*
+| from MovingHairGenerator
+*/
+float shaveVrayMovingVoxelPrim::getBend()
+{
+ return 0.0f;
+}
+int shaveVrayMovingVoxelPrim::generateStrand(int faceIndex, int strandIndex,
+ const VR::Vector *pv, const VR::Vector *nv,
+ VR::Vector *pts, VR::Vector *un, VR::Vector *vn)
+{
+ assert(false);
+ //maybe we do not need to change array elementws as far as we passed initalized strands
+ return true;
+}
+/*
+| from MovingHairGenerator
+*/
+VR::Vector shaveVrayMovingVoxelPrim::getStrandBaryCoords(int faceIndex, int strandIndex) const
+{
+ return VR::Vector(1.0f, 0.0f, 0.f);
+}
+/*
+| from MovingHairGenerator
+*/
+VR::Vector* shaveVrayMovingVoxelPrim::newVectors(int threadIndex)
+{
+ return (VR::Vector*) _pool_Vector().newElement();
+}
+/*
+| from MovingHairGenerator
+*/
+void shaveVrayMovingVoxelPrim::deleteVectors(VR::Vector *x, int threadIndex)
+{
+ _pool_Vector().releaseElement(x);
+}
+
+/*
+| from GeometryGenerator
+*/
+#if defined(VRAY30)
+VR::Vector shaveVrayMovingVoxelPrim::getGNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getGNormal(rsray);
+}
+VR::Vector shaveVrayMovingVoxelPrim::getNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getNormal(rsray);
+}
+#elif defined(VRAY40)
+VR::ShadeVec shaveVrayMovingVoxelPrim::getGNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getGNormal(rsray);
+}
+VR::ShadeVec shaveVrayMovingVoxelPrim::getNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getNormal(rsray);
+}
+#endif
+/*
+| from MovingPrimitive
+*/
+#if defined(VRAY30) || defined(VRAY40)
+/*
+ * ###########################################
+ * Implementation for V-Ray 3.0+
+ * ###########################################
+ */
+
+int shaveVrayMovingVoxelPrim::initHairData() {
+ const HairType &hair=voxel()->GetHair();
+ int numHairs=hair.GetNumStrands();
+
+ //assume all hairs have the same number of segments
+ _numknots()=hair.face_end[0]-hair.face_start[0];
+
+ for (int i=0; i<2; ++i) {
+ hairData[i].vertices=VR::VectorRefList(numHairs*_numknots());
+ hairData[i].time=float(i);
+ }
+ hairData[0].numVertices=VR::IntRefList(numHairs);
+ hairData[0].widths=VR::FloatRefList(numHairs*_numknots());
+ hairData[0].colors=VR::ColorRefList(numHairs*_numknots());
+ // share some arrays as they are the same
+ hairData[1].numVertices=hairData[0].numVertices;
+ hairData[1].widths=hairData[0].widths;
+ hairData[1].colors=hairData[0].colors;
+
+ VR::Vector scnoffs=VR::toVector(sceneOffset());
+ for (int g=0; g<numHairs; ++g) {
+ float root_radius=hair.radiusroot[g];
+ float delta_radius=hair.radiustip[g]-root_radius;
+ for (int k=0; k<numknots(); ++k) {
+ int knot_idx=hair.face_start[g]+k;
+ Vector p, v;
+ hair.GetVert(knot_idx, p.x, p.y, p.z);
+ p-=scnoffs;
+ hair.GetVelocity(knot_idx, v.x, v.y, v.z);
+
+ int hd_idx=numknots()*g+k;
+ hairData[0].vertices[hd_idx]=p;
+ hairData[1].vertices[hd_idx]=p+v;
+
+ float t=float(k)/float(numknots()-1);
+ float w=VR::Max(0.0001f, root_radius+t*delta_radius);
+ hairData[0].widths[hd_idx]=w;
+
+ VR::Color knot_color;
+ hair.GetVertColor(g, k, knot_color.r, knot_color.g, knot_color.b);
+ hairData[0].colors[hd_idx]=knot_color;
+ }
+ hairData[0].numVertices[g]=_numknots();
+ }
+
+ hairData[0].initVertexOffsets();
+ hairData[1].vertexOffsets=hairData[0].vertexOffsets;
+
+ for (int i=0; i<2; ++i) {
+ tmHairData[i].hairData=&hairData[i];
+ tmHairData[i].worldSpaceVertices=hairData[i].vertices;
+ tmHairData[i].initDirs();
+ tmHairData[i].time=float(i);
+ }
+
+ if (hinst()->plugin->dynHairTessel) {
+ tesselateHairData(tmHairData[0], &tessHairData[0],
+ &tmHairData[1], &tessHairData[1],
+ tessParams);
+ }
+
+ return numHairs;
+}
+
+#if defined(VRAY30)
+void shaveVrayMovingVoxelPrim::storeInGlobalTree(VR::RayServerInterface2 *rayserver)
+#elif defined(VRAY40)
+void shaveVrayMovingVoxelPrim::storeInGlobalTree(VR::RayServerInterface *rayserver)
+#endif
+{
+ if (!movingHairTree) {
+ int num_hairs=initHairData();
+ if(firstid()==-1)
+ _firstid()=rayserver->getNewRenderIDArray(num_hairs+1);
+ movingHairTree=new MovingHairTreePrimitive(firstid(), &tmHairData[0], &tmHairData[1], 0);
+ }
+ rayserver->storeMovingHairData(movingHairTree, this, firstid(), tmHairData[0], tmHairData[1]);
+}
+
+int shaveVrayMovingVoxelPrim::expand(VR::DynamicRaycaster<VR::MovingBox> *raycaster, int threadIndex) {
+
+ int num_hairs=initHairData();
+
+ if(firstid()==-1) _firstid()=raycaster->getNewRenderIDArray(num_hairs+1);
+
+#if VRAY_DLL_VERSION < 0x31000
+ movingHairTree=new MovingHairTreePrimitive(firstid()+1, &tmHairData[0], &tmHairData[1], true);
+#else
+#if VRAY_DLL_VERSION >= 0x40000
+ RayServerInterface* rayserver = vrayCore->getSequenceData().rayserver;
+#else
+ RayServerInterface2* rayserver = vrayCore->getSequenceData().rayserver;
+#endif
+ VoxelTree * tree = rayserver->newMovingVoxelTree(&tmHairData[0], tmHairData[0].time, tmHairData[1].time, voxelTreeType_hairTree);
+ movingHairTree=new MovingHairTreePrimitive(firstid()+1, &tmHairData[0], &tmHairData[1], tree);
+#endif
+ movingHairTree->build(prog, threadman, maxDepth, minLeaf, leafCoeff);
+
+ raycaster->insertPrimitive(threadIndex, movingHairTree, this, firstid());
+
+ int totalVertices=num_hairs*numknots();
+ uint64 memUsage=movingHairTree->getMemUsage();
+ return memUsage+3*2*sizeof(Vector)*totalVertices;
+}
+
+int shaveVrayMovingVoxelPrim::collapse(VR::DynamicRaycaster<VR::MovingBox> *raycaster, int threadIndex) {
+ raycaster->removePrimitive(threadIndex, movingHairTree);
+ uint64 memUsage=movingHairTree->getMemUsage();
+ delete movingHairTree;
+ movingHairTree=NULL;
+
+ memUsage+=3*2*sizeof(Vector)*tmHairData[1].hairData->vertices.size();
+
+ for (int i=0; i<2; ++i) {
+ tmHairData[i].freeMem();
+ hairData[i].freeMem();
+ tessHairData[i].freeMem();
+ }
+
+ return memUsage;
+}
+
+void shaveVrayMovingVoxelPrim::getMovingIntersectionData(int strandIdx, int segmentIdx, float time, Vector *p, Vector *dirs) {
+ int startIdx = tmHairData[0].hairData->vertexOffsets[strandIdx] + segmentIdx;
+
+ const Vector *p0 = &tmHairData[0].worldSpaceVertices[startIdx];
+ const Vector *dirs0 = &tmHairData[0].dirs[startIdx];
+
+ const Vector *p1 = &tmHairData[1].worldSpaceVertices[startIdx];
+ const Vector *dirs1 = &tmHairData[1].dirs[startIdx];
+
+ float time0=0.0f;//tmHairData[0].time;
+ float time1=1.0f;//tmHairData[1].time;
+ float k=(time-time0)/(time1-time0);
+ p[0] = p0[0]+(p1[0]-p0[0])*k;
+ p[1] = p0[1]+(p1[1]-p0[1])*k;
+
+ dirs[0] = dirs0[0]+(dirs1[0]-dirs0[0])*k;
+ dirs[1] = dirs0[1]+(dirs1[1]-dirs0[1])*k;
+}
+
+#if defined(VRAY30)
+void shaveVrayMovingVoxelPrim::setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const Vector &gNormal, const Vector &normal)
+#elif defined(VRAY40)
+void shaveVrayMovingVoxelPrim::setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const ShadeVec &gNormal, const ShadeVec &normal)
+#endif
+{
+ IntersectionData &isData=*((IntersectionData*) isd);
+ RSIntersection &is=rsray.is;
+
+ isData.primitive=rsray.is.primitive;
+ isData.skipTag=is.skipTag;
+
+ isData.sb=getShadeable();
+ isData.sd=getExtTexMapping();
+ isData.si=getExtShadeData();
+
+ isData.surfaceProps=NULL;
+ isData.volume=NULL;
+
+ isData.wpointCoeff=is.t;
+#if defined(VRAY30)
+ isData.wpoint=rsray.p+TracePoint(rsray.dir)*is.t;
+#elif defined(VRAY40)
+ isData.wpoint=rsray.p+rsray.dir*is.t;
+#endif
+
+ isData.gnormal=gNormal;
+ isData.normal=normal;
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ isData.extra_int[1]=strandIdx; // the hair strand index
+ isData.faceIndex=segmentIdx; // the segment index within a hair strand
+
+#if defined(VRAY30)
+ isData.bary = Vector(wParam, 0.0f, 0.0f); // the length along the segment
+
+ isData.faceBase = Vector(0.0f, 0.0f, 0.0f);
+ isData.faceEdge0 = Vector(0.0f, 0.0f, 0.0f);
+ isData.faceEdge1 = Vector(0.0f, 0.0f, 0.0f);
+#elif defined(VRAY40)
+ isData.bary = ShadeVec(wParam, 0.0f, 0.0f); // the length along the segment
+
+ isData.faceBase = ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.faceEdge0 = ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.faceEdge1 = ShadeVec(0.0f, 0.0f, 0.0f);
+#endif
+}
+
+#if defined(VRAY30)
+void shaveVrayMovingVoxelPrim::setCommonIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result,
+ const RAY_IDX idx, int strandIdx, int segmentIdx, float wParam,
+ const VUtils::Vector &gNormal, const VUtils::Vector &normal)
+{
+ VR::Ireal t = result.rayDistances()[ idx ];
+ for(int d=0; d<3; d++) result.isectPoints(d)[idx] = params.origins(d)[idx] + params.dirs(d)[idx] * t;
+
+ for(int d=0; d<3; d++) result.geomNormals(d)[idx] = gNormal[d];
+
+ for(int d=0; d<3; d++) result.smoothNormals(d)[idx] = normal[d];
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ result.extraInts(1)[idx] = strandIdx; // the hair strand index
+ result.faceIndices()[idx] = segmentIdx; // the segment index within a hair strand
+
+ VR::Vector bary = VR::Vector(wParam, 0.0f, 0.0f); // the length along the segment
+ for(int d=0; d<3; d++) result.baryCoords(d)[idx] = bary[d];
+
+ for(int d=0; d<3; d++) result.facesBase(d)[idx] = 0.0f;
+ for(int d=0; d<3; d++) result.facesEdge0(d)[idx] = 0.0f;
+ for(int d=0; d<3; d++) result.facesEdge1(d)[idx] = 0.0f;
+}
+#endif
+
+void shaveVrayMovingVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd) {
+ MovingHairTreePrimitive *treePrim=static_cast<MovingHairTreePrimitive*>(rsray.is.primitive);
+
+ int strandIdx=treePrim->getStrandIndex(rsray);
+ int segmentIdx=treePrim->getSegmentIndex(rsray);
+
+ Vector p[2], dirs[2];
+ getMovingIntersectionData(strandIdx, segmentIdx, rsray.time, p, dirs);
+
+ setCommonIntersectionData(rsray, isd, strandIdx, segmentIdx,
+ treePrim->getWparam(rsray, p),
+ treePrim->getGNormal(rsray, p),
+ treePrim->getNormal(rsray, p, dirs, getFlatNormal()));
+}
+
+#if defined(VRAY30)
+void shaveVrayMovingVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result,
+ const RAY_IDX* idxs, size_t count)
+{
+ // Iterate over the active rays
+ for( size_t i = 0; i < count; i++ ) {
+ const RAY_IDX idx = idxs[ i ];
+
+ MovingHairTreePrimitive *treePrim=static_cast<MovingHairTreePrimitive*>(result.primitives()[idx]);
+
+ int strandIdx=treePrim->getStrandIndex(params, result, idx);
+ int segmentIdx=treePrim->getSegmentIndex(params, result, idx);
+
+ Vector p[2], dirs[2];
+ getMovingIntersectionData(strandIdx, segmentIdx, params.times()[idx], p, dirs);
+
+ setCommonIntersectionData(params, result, idx, strandIdx, segmentIdx,
+ treePrim->getWparam(params, result, idx, p),
+ treePrim->getGNormal(params, result, idx, p),
+ treePrim->getNormal(params, result, idx, p, dirs, getFlatNormal()));
+ }
+}
+#endif
+
+VR::ShadeVec shaveVrayMovingVoxelPrim::getHairDir(const VR::VRayContext &rc) const {
+ const VR::Vector *vertices0 = tmHairData[0].worldSpaceVertices.get();
+ const VR::Vector *vertices1 = tmHairData[1].worldSpaceVertices.get();
+ VR::ShadeVec v0, v1, v2;
+
+ int strandIdx, segmentIdx;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx);
+
+ int pos=hairData[0].vertexOffsets[strandIdx]+segmentIdx;
+ float blend=rc.rayresult.bary[0];
+
+ VR::ShadeVec result(0.0f, 0.0f, 0.0f);
+
+ float k=(rc.rayparams.rayTime-tmHairData[0].time)/(tmHairData[1].time-tmHairData[0].time);
+ if (segmentIdx==0) {
+ VR::ShadeVec vertex0=VR::toShadeVec(vertices0[pos]);
+ VR::ShadeVec vertex1=VR::toShadeVec(vertices1[pos]);
+ VR::ShadeVec vertex0_next=VR::toShadeVec(vertices0[pos+1]);
+ VR::ShadeVec vertex1_next=VR::toShadeVec(vertices1[pos+1]);
+ v1=vertex0+(vertex1-vertex0)*k;
+ v2=vertex0_next+(vertex1_next-vertex0_next)*k;
+ result=normalize0(v2-v1);
+ } else {
+ VR::ShadeVec vertex0_prev=VR::toShadeVec(vertices0[pos-1]);
+ VR::ShadeVec vertex1_prev=VR::toShadeVec(vertices1[pos-1]);
+ VR::ShadeVec vertex0=VR::toShadeVec(vertices0[pos]);
+ VR::ShadeVec vertex1=VR::toShadeVec(vertices1[pos]);
+ VR::ShadeVec vertex0_next=VR::toShadeVec(vertices0[pos+1]);
+ VR::ShadeVec vertex1_next=VR::toShadeVec(vertices1[pos+1]);
+ v0=vertex0_prev+(vertex1_prev-vertex0_prev)*k;
+ v1=vertex0+(vertex1-vertex0)*k;
+ v2=vertex0_next+(vertex1_next-vertex0_next)*k;
+
+ VR::ShadeVec prev_dir=normalize0(v1-v0);
+ VR::ShadeVec curr_dir=normalize0(v2-v1);
+
+ result=normalize0(prev_dir + (curr_dir - prev_dir)*blend);
+ }
+
+ return result;
+}
+
+#else //VRAY30 not defined below this line
+/*
+ * ###########################################
+ * Implementation for V-Ray <= 2.99
+ * ###########################################
+ */
+
+int shaveVrayMovingVoxelPrim::expand (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex)
+{
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(numHairs == 0)
+ return 0;
+
+
+ int numblur_prims = numblur() - 1;
+ if(firstid() == -1)
+ _firstid() = raycaster->getNewRenderIDArray(numHairs*numblur_prims);
+
+ //assume all hairs have the same number of segments
+ _numknots() = hair.face_end[0] - hair.face_start[0];
+
+ int nalloc = numknots()*numHairs*numblur();
+ int nalloc2= numknots()*numHairs*numblur_prims;
+
+ _pts() = new VR::Vector[nalloc];
+ _dpts()= new VR::Vector[nalloc2];
+ _uns() = new VR::Vector[nalloc];
+ _duns()= new VR::Vector[nalloc2];
+ _vns() = new VR::Vector[nalloc];
+ _dvns()= new VR::Vector[nalloc2];
+
+ float step = 1.0f/(float)numblur_prims;
+
+ //calc point and vectors
+ for(int i = 0; i < numHairs; i++)
+ {
+ int strand_offset = i*numknots()*numblur();
+
+ float root_radius = hair.radiusroot[i];
+ float delta_radius = hair.radiustip[i] - root_radius;
+
+ //calc stuff for moving strands
+ for(int oo = 0; oo < numblur(); oo++)
+ {
+ float T = step*(float)oo;
+ int pts_offset = strand_offset + oo*numknots();
+
+ VR::Vector initialNormal;
+ VR::Vector sv0, sv1;
+ hair.GetVert(0, sv0.x, sv0.y, sv0.z);
+ hair.GetVert(1, sv1.x, sv1.y, sv1.z);
+ initialNormal=VR::normalize0(sv1-sv0);
+
+ // Compute the initial tangent vectors - these are later on propagated along the
+ // strand length to avoids issues with flipped tangent vectors.
+ VR::Vector u,v;
+ VR::computeTangentVectors(initialNormal, u, v);
+
+ VR::Vector v0;
+ for(int j = 0; j < numknots(); j++)
+ {
+ int vert_idx = hair.face_start[i] + j;
+ int pt_idx = pts_offset + j;
+
+ VR::Vector v1;
+ VR::Vector s(0.0f,0.0f,0.0f);
+ //not moved vert
+ hair.GetVert(vert_idx,v1.x,v1.y,v1.z);
+ //vertex velosity
+ hair.GetVelocity(vert_idx,s.x,s.y,s.z);
+
+ //calc moved vert locations
+ //v1 += (T + 0.5f)*s;
+ v1 += T*s;
+ _pt(pt_idx) = v1;
+ _pt(pt_idx) -= sceneOffset();
+
+ //calc un and vn
+ if(j == 0)
+ {
+ float radius = root_radius;
+ if (radius<0.001f) radius=0.001f;
+
+ // For the first point, just use the tangent vectors directly
+ _un(pt_idx) = u*radius;
+ _vn(pt_idx) = v*radius;
+ }
+ else
+ {
+ float t = (float)j/(float)(numknots()-1);
+ float radius = root_radius + t*delta_radius;
+
+ VR::Vector d=v1-v0;
+ float dlenSqr=d.lengthSqr();
+ if (dlenSqr>1e-12f) {
+ VR::Vector nu=u-d*((u*d)/sqrtf(dlenSqr)); // Project the previous u vector on the current cross plane
+ float nuLenSqr=lengthSqr(nu);
+ if (nuLenSqr>1e-12f) {
+ u=nu/sqrtf(nuLenSqr);
+ v=normalize(d^nu);
+ }
+ }
+
+ _un(pt_idx) = u*radius;
+ _vn(pt_idx) = v*radius;
+ }
+ v0 = v1;
+ }
+ }
+ }
+ //calc differences
+ for(int i = 0; i < numHairs; i++)
+ {
+ int strand_offset = i*numknots()*numblur();
+ int strand_offset2 = i*numknots()*numblur_prims;
+
+ for(int oo = 0; oo < numblur_prims; oo++)
+ {
+ int pts_offset0 = strand_offset + oo*numknots();
+ int pts_offset1 = pts_offset0 + numknots();
+ int pts_offset2 = strand_offset2+ oo*numknots();
+
+ for(int j = 0; j < numknots(); j++)
+ {
+ int pt_offset0 = pts_offset0 + j;
+ int pt_offset1 = pts_offset1 + j;
+ int pt_offset2 = pts_offset2 + j;
+
+ _dpt(pt_offset2) = pt(pt_offset1) - pt(pt_offset0);
+ _dun(pt_offset2) = un(pt_offset1) - un(pt_offset0);
+ _dvn(pt_offset2) = vn(pt_offset1) - vn(pt_offset0);
+ }
+ }
+ }
+
+ //alloc and place strands
+ int k = 0;
+ _strands() = new VR::MovingHairStrand[numHairs*numblur_prims];
+ for(int i = 0; i < numHairs; i++)
+ {
+ int strand_offset = i*numknots()*numblur();
+ int strand_offset2 = i*numknots()*numblur_prims;
+
+ for(int oo = 0; oo < numblur_prims; oo++)
+ {
+ float t0 = step*(float)oo;
+ float t1 = t0 + step;
+
+ int pts_offset0 = strand_offset + oo*numknots();
+ int pts_offset2 = strand_offset2 + oo*numknots();
+
+ _strand(i).init(static_cast<MovingHairGenerator*>(this),
+ t0, pts(pts_offset0), uns(pts_offset0), vns(pts_offset0),
+ t1, dpts(pts_offset2),duns(pts_offset2), dvns(pts_offset2));
+
+ raycaster->insertPrimitive(threadIndex, &_strand(i), static_cast<GeometryGenerator*>(this), k + firstid());
+ k++;
+ }
+ }
+
+ return numHairs*numblur_prims*sizeof(VR::MovingHairStrand) +
+ nalloc*3*sizeof(VR::Vector)+
+ nalloc2*3*sizeof(VR::Vector);
+}
+
+/*
+| from MovingPrimitive
+*/
+int shaveVrayMovingVoxelPrim::collapse (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex)
+{
+ // DebugPrint("PRIM> shaveVrayMovingVoxelPrim::collapse\n");
+
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(numHairs == 0)
+ return 0;
+
+ if(strands())
+ {
+ int n = numHairs*(numblur()-1);
+ for (int i=0; i < n; i++)
+ raycaster->removePrimitive(threadIndex, &_strand(i));
+
+ delete[] strands();
+ _strands() = NULL;
+ }
+ if(pts())
+ {
+ delete [] pts();
+ _pts() = NULL;
+ }
+ if(dpts())
+ {
+ delete [] dpts();
+ _dpts() = NULL;
+ }
+ if(uns())
+ {
+ delete [] uns();
+ _uns() = NULL;
+ }
+ if(duns())
+ {
+ delete [] duns();
+ _duns() = NULL;
+ }
+ if(dvns())
+ {
+ delete [] dvns();
+ _dvns() = NULL;
+ }
+ _pool_Vector().freeMem();
+
+ return numHairs*(numblur()-1)*sizeof(VR::MovingHairStrand) +
+ numHairs*(numblur()-1)*3*sizeof(VR::Vector) +
+ numHairs*numblur()*3*sizeof(VR::Vector);
+}
+
+/*
+| from GeometryGenerator
+*/
+void shaveVrayMovingVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd)
+{
+ VR::IntersectionData &isData=*((VR::IntersectionData*) isd);
+ VR::RSIntersection &is=rsray.is;
+
+ //assert(PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE == is.primitive->type());
+
+ VR::MovingHairStrand *s=(VR::MovingHairStrand*) (is.primitive->owner);
+
+ isData.primitive=is.primitive;
+ isData.skipTag =is.skipTag;
+ isData.faceIndex= (s->ownerIndex - firstid())/(numblur()-1);
+
+ if(ownbsdf())
+ isData.sb = shade();
+ else
+ isData.sb = shdata();
+
+ isData.sd = shdata();
+ isData.si = /*NULL;*/ shinst();
+ isData.volume=NULL;
+
+ isData.bary= VR::Vector(0.5f, 0.5f, 0.5f);
+ isData.wpointCoeff=is.t;
+ isData.gnormal=getGNormal(rsray);
+ isData.normal =getNormal(rsray);
+
+ isData.wpoint=rsray.p + VR::TracePoint(rsray.dir)*is.t;
+ //isData.wpoint= (rsray.p + VR::TracePoint(rsray.dir)*is.t) - sceneOffset();
+
+ isData.extraf=(float) s->getSegmentIndex((VR::MovingHairSegmentLine*) is.primitive);
+ isData.bary[2]=((VR::MovingHairSegmentLine*) is.primitive)->getWparam(rsray);
+
+// Vector *verts=fface->getVerts();
+// isData.faceBase=verts[0];
+// isData.faceEdge0=verts[1]-verts[0];
+// isData.faceEdge1=verts[2]-verts[0];
+
+ // We don't have any meaningful data here
+ isData.surfaceProps = NULL; // sfprops();
+}
+
+void shaveVrayMovingVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count)
+{
+ for(size_t ii=0; ii<count; ++ii) {
+ const RAY_IDX idx=idxs[ii];
+
+ VR::MovingHairSegmentLine *segment=static_cast<VR::MovingHairSegmentLine*>(result.primitives()[idx]);
+ VR::MovingHairStrand *strand=static_cast<VR::MovingHairStrand*>(segment->owner);
+
+ float t=result.rayDistances()[idx];
+ for(int d=0; d<3; d++)
+ result.isectPoints(d)[idx]=params.origins(d)[idx]+double(params.dirs(d)[idx])*t;
+
+ VR::Vector gnormal = segment->getGNormal(params, result, idx);
+ for(int d=0; d<3; d++)
+ result.geomNormals(d)[idx]=gnormal[d];
+
+ VR::Vector normal = segment->getNormal(params, result, idx);
+ for(int d=0; d<3; d++)
+ result.smoothNormals(d)[idx]=normal[d];
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ result.faceIndices()[idx]=strand->ownerIndex - firstid();
+ result.extraFloats(6)[idx]=(float)strand->getSegmentIndex(segment); // the segment index within a hair strand
+
+ VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment
+ for(int d=0; d<3; d++)
+ result.baryCoords(d)[idx]=bary[d];
+
+ for(int d=0; d<3; d++)
+ result.facesBase(d)[idx]=0.0f;
+ for(int d=0; d<3; d++)
+ result.facesEdge0(d)[idx]=0.0f;
+ for(int d=0; d<3; d++)
+ result.facesEdge1(d)[idx]=0.0f;
+ }
+}
+
+
+#endif //VRAY30
+
diff --git a/vrayPlug/plugin/shaveVrayMovingVoxelPrim.h b/vrayPlug/plugin/shaveVrayMovingVoxelPrim.h
new file mode 100644
index 0000000..d7a9932
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayMovingVoxelPrim.h
@@ -0,0 +1,232 @@
+#ifndef _HAIR_VR_MOVING_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_MOVING_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: HairVrStaticVoxelPrim.h
+
+ DESCRIPTION: Motion blurred hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 04-09-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 30-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayVoxelPrim.h"
+#include "hairprimitives.h"
+
+
+class shaveVrayMovingVoxelPrim : public shaveVrayVoxelPrim,
+ public VR::MovingHairGenerator {
+public:
+ shaveVrayMovingVoxelPrim(IHairVoxel* voxel, VR::VRayCore *vray,shaveVrayInstance* inst);
+ virtual ~shaveVrayMovingVoxelPrim();
+
+ /*
+ | from StaicPrimitive
+ */
+ // Return the bounding box of this primitive.
+ void getBBox (VR::MovingBox &bbox);
+
+ //Return true if the primitive is splittable.
+ bool splittable ();
+
+ //Return the bounding boxes of the primitive with respect to a given plane.
+ void split (int dim, VR::real middle, VR::MovingBox &bLeft, VR::MovingBox &bRight);
+
+ //Return true here
+ int expandable();
+
+ //Expand the primitive into other sub-primitives.
+ int expand (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex);
+
+ //Collapse the primitive.
+ int collapse (VR::DynamicRaycaster< VR::MovingBox > *raycaster, int threadIndex);
+
+ /*
+ | from StaicHairGenerator
+ */
+ // always returns 4
+ int getNumSides(void) const;
+
+ // number of segments in the strand
+ int getNumKnots(void);
+
+ // returns two arrays, of getNumSides() length each,
+ // with the cosine and sine along the circle at regular intervals
+ void getSidesUV(float *&uc, float *&vc);
+ // vlad|8Apr2010 - uc,vc are const now
+ void getSidesUV(const float *&uc, const float *&vc) const;
+
+ //return true to use a simplified normal calculation inside the
+ //StaticHairSegmentLine::getNormal() and getGNormal(), and false to use a more correct model
+ int getFlatNormal(void) const;
+
+ //not sure about these
+ float getRadius();
+ float getLength();
+ float getTaper();
+
+ //hair engine hanles gravity and other forces
+ VR::Vector getGravity();
+
+ //we return 0.0f for all of these
+ float getLengthRand();
+ float getRadiusRand();
+ float getGravityRand();
+ float getDirRand();
+ float getBend();
+
+ int generateStrand(int faceIndex, int strandIndex,
+ const VR::Vector *pv, const VR::Vector *nv,
+ VR::Vector *pts, VR::Vector *un, VR::Vector *vn);
+
+ VR::Vector getStrandBaryCoords(int faceIndex, int strandIndex) const;
+
+ VR::Vector* newVectors(int threadIndex);
+ void deleteVectors(VR::Vector *x, int threadIndex);
+
+ /*
+ | from GeometryGenerator
+ */
+#if defined(VRAY30)
+ VR::Vector getGNormal(VR::RSRay &rsray);
+ VR::Vector getNormal(VR::RSRay &rsray);
+#elif defined(VRAY40)
+ VR::ShadeVec getGNormal(VR::RSRay &rsray);
+ VR::ShadeVec getNormal(VR::RSRay &rsray);
+#endif
+ void setIntersectionData(VR::RSRay &rsray, void *isData);
+#if defined(VRAY30)
+ void setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count);
+#endif
+
+ VR::Shadeable* getShadeable() { return ownbsdf() ? shade() : shdata(); }
+ VR::VRayShadeInstance* getExtShadeData() { return shinst(); }
+ VR::VRayShadeData* getExtTexMapping() { return shdata(); }
+ VR::VRayVolume* getVolumeShader() { return NULL; }
+ VR::VRaySurfaceProperties* getExtSurfaceProperties() { return NULL; }
+
+#if defined(VRAY30)
+ void storeInGlobalTree(VR::RayServerInterface2 *rayserver);
+#elif defined(VRAY40)
+ void storeInGlobalTree(VR::RayServerInterface *rayserver);
+#endif
+#if defined(VRAY30) || defined(VRAY40)
+
+ // no need to implement, that is used by our automatic hair generation primitives
+ int generateStrand(int faceIndex, int strandIndex, int threadIndex, float time, const VR::Vector *pv,
+ const VR::Vector *nv, VR::Vector *pts, VR::Vector *un, VR::Vector *vn)
+ {
+ return 0;
+ }
+
+ VR::ShadeVec getHairDir(const VR::VRayContext &rc) const;
+#endif
+
+ //VR::Vector getGNormal(VR::RSRayRef& rsrayref);
+ //VR::Vector getNormal(VR::RSRayRef& rsrayref);
+ //void setIntersectionData(VR::RSRayRef& rsrayref, void *isData);
+
+protected:
+#if defined(VRAY30)
+ void setCommonIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result,
+ const RAY_IDX idx, int strandIdx, int segmentIdx, float wParam,
+ const VUtils::Vector &gNormal, const VUtils::Vector &normal);
+ void setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const VR::Vector &gNormal, const VR::Vector &normal) ;
+#elif defined(VRAY40)
+ void setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const VR::ShadeVec &gNormal, const VR::ShadeVec &normal) ;
+#endif
+#if defined(VRAY30) || defined(VRAY40)
+ void getMovingIntersectionData(int strandIdx, int segmentIdx, float time, VR::Vector *p, VR::Vector *dirs);
+
+ // Returns the number of hair strands
+ int initHairData();
+#endif
+
+ //const member access
+ inline const VR::MovingHairStrand& strand(int i) const {return m_strands[i];}
+ inline VR::MovingHairStrand* strands()const {return m_strands;}
+ inline const VR::Vector& pt(int i) const {return m_pts[i];}
+ inline const VR::Vector& dpt(int i)const {return m_dpts[i];}
+ inline const VR::Vector& un(int i) const {return m_uns[i];}
+ inline const VR::Vector& dun(int i)const {return m_duns[i];}
+ inline const VR::Vector& vn(int i) const {return m_vns[i];}
+ inline const VR::Vector& dvn(int i)const {return m_dvns[i];}
+ inline const VR::MovingBox& bbox() const {return m_bbox;}
+ inline VR::Vector* pts(int offset) const {return &m_pts[offset];}
+ inline VR::Vector* uns(int offset) const {return &m_uns[offset];}
+ inline VR::Vector* vns(int offset) const {return &m_vns[offset];}
+ inline VR::Vector* dpts(int offset) const {return &m_dpts[offset];}
+ inline VR::Vector* duns(int offset) const {return &m_duns[offset];}
+ inline VR::Vector* dvns(int offset) const {return &m_dvns[offset];}
+ inline VR::Vector* pts() const {return m_pts;}
+ inline VR::Vector* dpts() const {return m_dpts;}
+ inline VR::Vector* uns() const {return m_uns;}
+ inline VR::Vector* duns() const {return m_duns;}
+ inline VR::Vector* vns() const {return m_vns;}
+ inline VR::Vector* dvns() const {return m_dvns;}
+ inline int firstid() const {return m_firstid;}
+ inline int numblur() const {return m_numblur;}
+
+ //member access
+ inline VR::MovingHairStrand& _strand(int i) {return m_strands[i];}
+ inline VR::MovingHairStrand*& _strands() {return m_strands;}
+ inline VR::MovingBox& _bbox() {return m_bbox;}
+ inline VR::Vector& _pt(int i) {return m_pts[i];}
+ inline VR::Vector& _dpt(int i){return m_dpts[i];}
+ inline VR::Vector& _un(int i) {return m_uns[i];}
+ inline VR::Vector& _dun(int i){return m_duns[i];}
+ inline VR::Vector& _vn(int i) {return m_vns[i];}
+ inline VR::Vector& _dvn(int i){return m_dvns[i];}
+ inline VR::Vector*& _pts() {return m_pts;}
+ inline VR::Vector*& _dpts() {return m_dpts;}
+ inline VR::Vector*& _uns() {return m_uns;}
+ inline VR::Vector*& _duns() {return m_duns;}
+ inline VR::Vector*& _vns() {return m_vns;}
+ inline VR::Vector*& _dvns() {return m_dvns;}
+ inline int& _firstid() {return m_firstid;}
+ inline int& _numblur() {return m_numblur;}
+
+private:
+
+ int m_firstid;
+ int m_numblur;
+ VR::Vector* m_pts;
+ VR::Vector* m_dpts;
+ VR::Vector* m_uns;
+ VR::Vector* m_duns;
+ VR::Vector* m_vns;
+ VR::Vector* m_dvns;
+ VR::MovingHairStrand* m_strands;
+ VR::MovingBox m_bbox;
+#if defined(VRAY30) || defined(VRAY40)
+ VR::HairData hairData[2];
+ VR::HairData tessHairData[2];
+ VR::TransformedHairData tmHairData[2];
+
+ VR::MovingHairTreePrimitive *movingHairTree;
+
+ int maxDepth;
+ float minLeaf;
+ float leafCoeff;
+
+ VUtils::TessHairParams tessParams;
+
+ VR::ThreadManager *threadman;
+ VR::ProgressCallback *prog;
+#endif
+};
+
+
+#endif //endof_HAIR_VR_MOVING_VOXEL_PRIMITIVE_H_
+
diff --git a/vrayPlug/plugin/shaveVrayPlugin.cpp b/vrayPlug/plugin/shaveVrayPlugin.cpp
new file mode 100644
index 0000000..8f1de65
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayPlugin.cpp
@@ -0,0 +1,306 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayPlugin.cpp
+
+ DESCRIPTION: VRay plugin
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 30-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayPlugin.h"
+#include "shaveVrayInstance.h" //regular hair
+#include "shaveVrayInstanceI.h" //instnanced hair
+#include "shaveVraySharedFunctions.h"
+
+#include <iostream>
+#include <stdexcept>
+#include <stdlib.h>
+
+extern "C"
+{
+#include "shaveSDKFUNCS2.h"
+}
+
+#ifdef WIN32
+FILE* alog = NULL;
+#endif
+
+VR::CharString shaveVrayPlugin::draFile = VR::CharString();
+
+const char* shaveVrayPlugin::version = "v1.0.18";
+
+void shaveVrayPlugin::pause(int minSeconds, int maxSeconds)
+{
+ int range = maxSeconds - minSeconds + 1;
+ int delayInSeconds = (int)((float)rand() / (((float)RAND_MAX) + 1.0f) * (float)(range+1)) + minSeconds;
+
+#ifdef _WIN32
+ Sleep(delayInSeconds * 1000);
+#else
+ sleep(delayInSeconds);
+#endif
+}
+
+
+shaveVrayPlugin::shaveVrayPlugin(VR::VRayPluginDesc *desc)
+ : VRayStaticGeomSource(desc)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin ctor");
+ //LOGMSGS("SHAVE","version",version);
+ fprintf(stdout,"SHAVE: Shave and A Haircut for V-Ray (%s)\n",version);
+ fprintf(stdout,"SHAVE: Shave core (%s)\n",SHAVE2query_version());
+ fprintf(stdout,"SHAVE: (c) 2019 Epic Games\n");
+ fflush(stdout);
+
+ //LOGMSG("SHAVE","SHAVE2init");
+ //SHAVE2init(); //crash on mac
+
+ _instanced() = 0;
+ _stackIndex()= 0;
+
+ ctxs=NULL;
+
+ paramList->setParamCache(VR30_CONST_STR_HACK("stackId"), &m_stackIndex);
+ paramList->setParamCache(VR30_CONST_STR_HACK("instanced"), &m_instanced);
+ paramList->setParamCache(VR30_CONST_STR_HACK("ownshader"), &m_ownshader);
+ paramList->setParamCache(VR30_CONST_STR_HACK("squirrel"), &m_squirrel);
+ paramList->setParamCache(VR30_CONST_STR_HACK("tipfade"), &m_tipfade);
+ paramList->setParamCache(VR30_CONST_STR_HACK("spectint"), &m_spectint);
+ paramList->setParamCache(VR30_CONST_STR_HACK("spectint2"), &m_spectint2);
+ paramList->setParamCache(VR30_CONST_STR_HACK("draFile"), &draFile);
+ paramList->setParamCache(VR30_CONST_STR_HACK("libPath"), &m_libPath);
+ //instance uvs-related params
+ paramList->setParamCache(VR30_CONST_STR_HACK("numFacesPerInst"), &m_numFacesPerInst);
+ paramList->setParamCache(VR30_CONST_STR_HACK("numUVSets"), &m_numUVSets);
+ //ray visibility params
+ paramList->setParamCache(VR30_CONST_STR_HACK("cameraVisibility"), &m_cameraVisibility);
+ paramList->setParamCache(VR30_CONST_STR_HACK("reflVisibility"), &m_reflVisibility);
+ paramList->setParamCache(VR30_CONST_STR_HACK("refrVisibility"), &m_refrVisibility);
+ paramList->setParamCache(VR30_CONST_STR_HACK("lightVisibility"), &m_lightVisibility);
+ paramList->setParamCache(VR30_CONST_STR_HACK("GiVisibility"), &m_GiVisibility);
+ paramList->setParamCache(VR30_CONST_STR_HACK("selfShadow"), &m_selfShadow);
+ paramList->setParamCache(VR30_CONST_STR_HACK("recvShadow"), &m_recvShadow);
+#if defined(VRAY30) || defined(VRAY40)
+ paramList->setParamCache(VR30_CONST_STR_HACK("useGlobalHairTree"), &useGlobalHairTree);
+ paramList->setParamCache(VR30_CONST_STR_HACK("dynamicHairTesselation"), &dynHairTessel);
+ paramList->setParamCache(VR30_CONST_STR_HACK("hairTesselMaxEdgleLen"), &edgeLen);
+#endif
+
+ LOGMSG("SHAVE","shaveVrayPlugin ctor - OK");
+}
+
+shaveVrayPlugin::~shaveVrayPlugin()
+{
+ LOGMSG("SHAVE","shaveVrayPlugin dtor");
+
+ freeMem();
+#ifdef WIN32
+ assert(_CrtCheckMemory());
+#endif
+ LOGMSG("SHAVE","shaveVrayPlugin dtor - OK");
+}
+
+void shaveVrayPlugin::freeMem()
+{
+ if (ctxs)
+ {
+ for (int threadIdx=0; threadIdx < numThreads; threadIdx++)
+ if (ctxs[threadIdx])
+ ctxs[threadIdx]->releaseContext();
+ delete[] ctxs;
+ ctxs=NULL;
+ }
+}
+
+void shaveVrayPlugin::createRayContextes(VR::VRayRenderer *vray)
+{
+ numThreads = vray->getSequenceData().maxRenderThreads;
+
+ ctxs = new VR::VRayContext*[numThreads];
+
+ for (int threadIdx=0; threadIdx<numThreads; threadIdx++)
+ {
+ ctxs[threadIdx] = ((vray->getThreadData(threadIdx))->newVRayContext());
+ VR::VRayContext &rc = *(ctxs[threadIdx]);
+
+ rc.clear();
+ VR::TraceRay tray;
+#if defined(VRAY30)
+ tray.p=VR::TracePoint(0.0f, 0.0f, 0.0f);
+ tray.dir=VR::Vector(0.0f, 0.0f, 1.0f);
+ rc.setRay(0.0f, 0.0f, tray, VR::RT_CAMERA , 0.0f, 0.0f, LARGE_FLOAT);
+#elif defined(VRAY40)
+ tray.p=VR::simd::Vector3f(0.0f, 0.0f, 0.0f);
+ tray.dir=VR::simd::Vector3f(0.0f, 0.0f, 1.0f);
+ VR::ShadeCol multResult;
+ multResult.makeWhite();
+ rc.setRay(0.0f, 0.0f, tray, VR::RayFlags(VR::RT_CAMERA), 0.0f, 0.0f, LARGE_FLOAT);
+#endif
+ // rc.rayparams.computeGBuffer=false;
+
+ VR::IntersectionData isData;
+ isData.primitive=NULL;
+ isData.skipTag=NULL;
+ isData.faceIndex=0;
+ isData.sb=NULL;
+ isData.si=NULL;
+ isData.sd=NULL;
+ isData.surfaceProps=NULL;
+ isData.volume=NULL;
+ isData.wpointCoeff=1.0f;
+
+#if defined(VRAY30) || defined(VRAY40)
+ isData.bary=VR::ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.wpoint=VR::ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.faceBase=isData.faceEdge0=isData.faceEdge1=VR::ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.gnormal=isData.normal=VR::ShadeVec(0.0f, 0.0f, 1.0f);
+#endif
+
+ rc.setRayResult(true, &isData, 0);
+#if defined(VRAY30) || defined(VRAY40)
+ rc.rayresult.dPdx=VR::ShadeVec(0.0f, 0.0f, 0.0f);
+ rc.rayresult.dPdy=VR::ShadeVec(0.0f, 0.0f, 0.0f);
+#endif
+ }
+}
+
+// true if SHAVE2init() has been called so that we know to call SHAVE2cleanup() when the plugin is unloaded.
+int shaveInitCalled=false;
+
+// Critical section for accessing shaveInitCalled in case we have multiple renders going on at the same time
+VUtils::CriticalSection shaveInit_csect;
+
+static bool isRenderStarted = false;
+void shaveVrayPlugin::renderBegin(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin::renderBegin");
+
+ VR::ProgressCallback* progress = NULL;
+ if (vray != NULL)
+ {
+ const VR::VRaySequenceData &sdata=vray->getSequenceData();
+ progress = sdata.progress;
+ }
+
+ // Initialize Shave (just once, the first time we render)
+ if (!shaveInitCalled) {
+ VUtils::CriticalSectionRAII lock(shaveInit_csect);
+ if (!shaveInitCalled) {
+ SHAVE2init();
+ shaveInitCalled=true;
+ }
+ }
+
+ VRayStaticGeomSource::renderBegin(vray);
+
+ LOGMSG("SHAVE","shaveVrayPlugin::renderBegin - OK");
+}
+
+void shaveVrayPlugin::renderEnd(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin::renderEnd");
+
+ UnLoadShaveBSDFPoolLib();
+
+ VR::ProgressCallback* progress = NULL;
+ if (vray != NULL)
+ {
+ const VR::VRaySequenceData &sdata=vray->getSequenceData();
+ progress = sdata.progress;
+ }
+
+ VRayStaticGeomSource::renderEnd(vray);
+
+ LOGMSG("SHAVE","shaveVrayPlugin::renderEnd - OK");
+}
+
+void shaveVrayPlugin::frameBegin(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin::frameBegin");
+
+ VRayStaticGeomSource::frameBegin(vray);
+
+ //this->vray = vray;
+ //double time=vray->getFrameData().t;
+
+ //meshInfoInterface = (MeshInfoInterface*)GET_INTERFACE(meshPlugin, EXT_MESH_INFO);
+
+ ////getIntListData(faceList, paramList->getParam("faceList"), time);
+ ////getFloatListData(areaList, paramList->getParam("areaList"), time);
+
+ createRayContextes(vray);
+
+ ////we need to export DRA or use dra exported in shaves ::compute ?
+
+ LOGMSG("SHAVE","shaveVrayPlugin::frameBegin - OK");
+}
+
+void shaveVrayPlugin::frameEnd(VR::VRayRenderer *vray)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin::frameEnd");
+
+ freeMem();
+
+ LOGMSG("SHAVE","shaveVrayPlugin::frameEnd - OK");
+}
+
+VR::VRayStaticGeometry* shaveVrayPlugin::newInstance(
+ VR::MaterialInterface *mtl,
+ VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#ifdef VRAY40
+ const VR::Transform &baseTM,
+#else
+ const VR::TraceTransform &baseTM,
+#endif
+ int objectID, const tchar *userAttributes, int primaryVisibility) {
+
+ LOGMSG("SHAVE","shaveVrayPlugin::newInstance");
+
+ LoadShaveBSDFPoolLib(m_libPath.ptr());
+
+ if(instanced() == 1)
+ {
+ return new shaveVrayInstanceI(this, mtl, bsdf, renderID, volume, lightList, baseTM, objectID,
+ userAttributes, m_cameraVisibility);
+ }
+ else
+ {
+ //we gonna use own bsdf
+ return new shaveVrayInstance(this, mtl, bsdf, renderID, volume, lightList, baseTM, objectID,
+ userAttributes, m_cameraVisibility);
+ }
+}
+
+void shaveVrayPlugin::deleteInstance(VR::VRayStaticGeometry *instance)
+{
+ LOGMSG("SHAVE","shaveVrayPlugin::deleteInstance");
+
+ delete (shaveVrayInstance*)instance;
+}
+
+VR::VRayContext* shaveVrayPlugin::getVRayContext()
+{
+ VR::ThreadManager *threadMan = (const_cast<VR::VRaySequenceData&>(vray->getSequenceData())).threadManager;
+ if (threadMan) {
+ int tIdx = threadMan->getThreadIndex(); // This didn't seem to work in my tests, returned -1
+ if (tIdx==-1)
+ return ctxs[0];
+ else
+ return ctxs[tIdx];
+ }
+ return ctxs[0];
+}
+
+
+
+
+
diff --git a/vrayPlug/plugin/shaveVrayPlugin.h b/vrayPlug/plugin/shaveVrayPlugin.h
new file mode 100644
index 0000000..e0f47e2
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayPlugin.h
@@ -0,0 +1,233 @@
+#ifndef _HAIR_VRAY_PLUGIN_H_
+#define _HAIR_VRAY_PLUGIN_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayPlugin.h
+
+ DESCRIPTION: VRay plugin
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 30-03-2010
+
+ *>
+ **********************************************************************/
+
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "meshinfointerface.h"
+#include "defparams.h"
+#include "charstring.h"
+
+#ifdef VRAY30
+ #define VR30_CONST_STR_HACK(x) const_cast<char*>(x)
+#else
+ #define VR30_CONST_STR_HACK(x) x
+#endif
+
+#include <stdio.h>
+
+class shaveVrayPlugin : public VR::VRayStaticGeomSource{
+public:
+ static const char* version;
+ VR::VRayRenderer *vray;
+
+#if defined(VRAY30) || defined(VRAY40)
+ int useGlobalHairTree;
+ int dynHairTessel;
+ float edgeLen;
+#endif
+
+ // Cache for the parameters
+ //not sure what for these are used
+ //PluginBase *meshPlugin;
+ //MeshInfoInterface *meshInfoInterface;
+
+
+ shaveVrayPlugin(VR::VRayPluginDesc *desc);
+ ~shaveVrayPlugin();
+
+ void freeMem();
+
+ // From VRayPlugin
+ void renderBegin(VR::VRayRenderer *vray);
+ void renderEnd(VR::VRayRenderer *vray);
+ void frameBegin(VR::VRayRenderer *vray);
+ void frameEnd(VR::VRayRenderer *vray);
+
+ // From VRayStaticGeomSource
+ VR::VRayStaticGeometry* newInstance(
+ VR::MaterialInterface *mtl,
+ VR::BSDFInterface *bsdf, int renderID,
+ VR::VolumetricInterface *volume, VR::LightList *lightList,
+#ifdef VRAY40
+ const VR::Transform &baseTM,
+#else
+ const VR::TraceTransform &baseTM,
+#endif
+ int objectID, const tchar *userAttributes, int primaryVisibility);
+
+ void deleteInstance(VR::VRayStaticGeometry *instance);
+
+ VR::VRayContext* getVRayContext();
+
+ void SetStackIndex(int idx) {_stackIndex() = idx;}
+ int GetStackIndex() const {return stackIndex();}
+
+ void SetUseOwnBSDF(bool use) {_ownshader() = use ? 1 : 0;}
+ bool GetUseOwnBSDF() const {return ownshader() != 0;}
+
+ bool GetSquirrel() const {return squirrel() != 0;}
+ bool GetTipFade() const {return tipfade() != 0;}
+
+ const VR::Color& GetSpecTint() const {return spectint();}
+ const VR::Color& GetSpecTint2() const {return spectint2();}
+
+ inline bool GetCameraVisibility() const {return cameraVisibility() != 0;}
+ inline bool GetReflVisibility() const {return reflVisibility() != 0;}
+ inline bool GetRefrVisibility() const {return refrVisibility() != 0;}
+ inline bool GetLightVisibility() const {return lightVisibility() != 0;}
+ inline bool GetGiVisibility() const {return GiVisibility() != 0;}
+
+ inline float GetSelfShadow() const {return selfShadow();}
+ inline bool GetRecvShadow() const {return recvShadow();}
+
+ //const VR::Vector& GetUVs() const {return uvs();}
+ int GetNumFacesPerInst() const {return numFacesPerInst();}
+ int GetNumUVSets() const {return numUVSets();}
+
+ //does not work for standalone
+ //shaveVrayVectorListParam* GetUVparam() const
+ //{
+ // return m_uvsParam;
+ //}
+ //shaveVrayIntListParam* GetDataParam() const
+ //{
+ // return m_dataParam;
+ //}
+ //shaveVrayIntParam* GetDataSizeParam() const
+ //{
+ // return m_dataSizeParam;
+ //}
+
+protected:
+
+ int numThreads;
+ VR::VRayContext **ctxs; // used for sampling the textures
+
+ void createRayContextes(VR::VRayRenderer *vray);
+
+ //const member access
+ inline int stackIndex() const {return m_stackIndex;}
+ inline int instanced() const {return m_instanced;}
+ inline int ownshader() const {return m_ownshader;}
+ inline int numFacesPerInst()const {return m_numFacesPerInst;}
+ inline int numUVSets() const {return m_numUVSets;}
+ //inline const VR::Vector& uvs() const {return m_uvs;}
+ inline int squirrel() const {return m_squirrel;}
+ inline int tipfade() const {return m_tipfade;}
+ inline const VR::Color& spectint() const {return m_spectint;}
+ inline const VR::Color& spectint2()const {return m_spectint2;}
+ inline int cameraVisibility() const {return m_cameraVisibility;}
+ inline int reflVisibility() const {return m_reflVisibility;}
+ inline int refrVisibility() const {return m_refrVisibility;}
+ inline int lightVisibility() const {return m_lightVisibility;}
+ inline int GiVisibility() const {return m_GiVisibility;}
+ inline float selfShadow() const {return m_selfShadow;}
+ inline int recvShadow() const {return m_recvShadow;}
+
+ //member access
+ inline int& _stackIndex() {return m_stackIndex;}
+ inline int& _instanced() {return m_instanced;}
+ inline int& _ownshader() {return m_ownshader;}
+ inline int& _numFacesPerInst() {return m_numFacesPerInst;}
+ inline int& _numUVSets() {return m_numUVSets;}
+ //inline VR::Vector& _uvs() {return m_uvs;}
+ inline int& _squirrel() {return m_squirrel;}
+ inline int& _tipfade() {return m_tipfade;}
+ inline VR::Color& _spectint() {return m_spectint;}
+ inline VR::Color& _spectint2() {return m_spectint2;}
+ inline int& _cameraVisibility(){return m_cameraVisibility;}
+ inline int& _reflVisibility() {return m_reflVisibility;}
+ inline int& _refrVisibility() {return m_refrVisibility;}
+ inline int& _lightVisibility() {return m_lightVisibility;}
+ inline int& _GiVisibility() {return m_GiVisibility;}
+ inline float& _selfShadow() {return m_selfShadow;}
+ inline int& _recvShadow() {return m_recvShadow;}
+
+ static void pause(int minSeconds, int maxSeconds);
+
+private:
+
+ int m_instanced;
+ int m_stackIndex;
+ int m_ownshader;
+ int m_numFacesPerInst;
+ int m_numUVSets;
+ int m_squirrel;
+ int m_tipfade;
+ VR::Color m_spectint;
+ VR::Color m_spectint2;
+ VR::CharString m_libPath;
+ //VR::Vector m_uvs;
+ int m_cameraVisibility;
+ int m_reflVisibility;
+ int m_refrVisibility;
+ int m_lightVisibility;
+ int m_GiVisibility;
+ float m_selfShadow;
+ int m_recvShadow;
+
+public:
+ static VR::CharString draFile;
+};
+
+#define DO_LOGS
+#ifdef DO_LOGS
+
+#ifdef WIN32
+ extern FILE* alog;
+#define LOGMSG(prefix, msg) {if(alog){ fprintf(alog,"%s> %s\n",prefix,msg);fflush(alog);}}
+#else
+#define LOGMSG(prefix, msg) {fprintf(stdout,"%s> %s\n",prefix,msg);fflush(stdout);}
+#endif
+
+#ifdef WIN32
+ extern FILE* alog;
+#define LOGMSGS(prefix, msg1, msg2) {if(alog){ fprintf(alog,"%s> %s %s\n",prefix,msg1,msg2);;fflush(alog);}}
+#else
+#define LOGMSGS(prefix, msg1, msg2) {fprintf(stdout,"%s> %s %s\n",prefix,msg1,msg2);fflush(stdout);}
+#endif
+
+#ifdef WIN32
+ extern FILE* alog;
+#define LOGMSGI(prefix, msg1, i) {if(alog){ fprintf(alog,"%s> %s %i\n",prefix,msg1,i);;fflush(alog);}}
+#else
+#define LOGMSGI(prefix, msg1, i) {fprintf(stdout,"%s> %s %i\n",prefix,msg1,i);fflush(stdout);}
+#endif
+
+#ifdef WIN32
+ extern FILE* alog;
+#define LOGMSGI3(prefix, msg1, i1, i2, i3){if(alog) {fprintf(alog,"%s> %s %i %i %i\n",prefix,msg1,i1,i2,i3);fflush(alog);}}
+#else
+#define LOGMSGI3(prefix, msg1, i1, i2, i3) {fprintf(stdout,"%s> %s %i %i %i\n",prefix,msg1,i1,i2,i3);fflush(stdout);}
+#endif
+
+#else //DO_LOGS
+
+#define LOGMSG(prefix, msg) {;}
+#define LOGMSGS(prefix, msg1, msg2) {;}
+#define LOGMSGI(prefix, msg1, i) {;}
+#define LOGMSGI3(prefix, msg1, i1, i2, i3){;}
+
+#endif //DO_LOGS
+
+#endif //end of_HAIR_VRAY_PLUGIN_H_
+
diff --git a/vrayPlug/plugin/shaveVraySh-vs11.sln b/vrayPlug/plugin/shaveVraySh-vs11.sln
new file mode 100644
index 0000000..d560672
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySh-vs11.sln
@@ -0,0 +1,44 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaveVraySh", "shaveVraySh-vs11.vcxproj", "{67281644-B839-42DE-A013-38725B2DE280}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseVray36|Win32 = ReleaseVray36|Win32
+ ReleaseVray36|x64 = ReleaseVray36|x64
+ ReleaseVray36-direct|Win32 = ReleaseVray36-direct|Win32
+ ReleaseVray36-direct|x64 = ReleaseVray36-direct|x64
+ ReleaseVray40|Win32 = ReleaseVray40|Win32
+ ReleaseVray40|x64 = ReleaseVray40|x64
+ ReleaseVray40-direct|Win32 = ReleaseVray40-direct|Win32
+ ReleaseVray40-direct|x64 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {67281644-B839-42DE-A013-38725B2DE280}.Debug|Win32.ActiveCfg = Debug|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Debug|x64.ActiveCfg = Debug|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Debug|x64.Build.0 = Debug|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Release|Win32.ActiveCfg = Release|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Release|x64.ActiveCfg = Release|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Release|x64.Build.0 = Release|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36|Win32.ActiveCfg = ReleaseVray36|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36|x64.ActiveCfg = ReleaseVray36|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36|x64.Build.0 = ReleaseVray36|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36-direct|Win32.ActiveCfg = ReleaseVray36-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36-direct|x64.ActiveCfg = ReleaseVray36-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36-direct|x64.Build.0 = ReleaseVray36-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40|Win32.ActiveCfg = ReleaseVray40|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40|x64.ActiveCfg = ReleaseVray40|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40|x64.Build.0 = ReleaseVray40|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40-direct|Win32.ActiveCfg = ReleaseVray40-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40-direct|x64.ActiveCfg = ReleaseVray36-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40-direct|x64.Build.0 = ReleaseVray36-direct|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vrayPlug/plugin/shaveVraySh-vs11.vcxproj b/vrayPlug/plugin/shaveVraySh-vs11.vcxproj
new file mode 100644
index 0000000..cb552c1
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySh-vs11.vcxproj
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug 2012|x64">
+ <Configuration>Debug 2012</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36-direct|x64">
+ <Configuration>ReleaseVray36-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36|x64">
+ <Configuration>ReleaseVray36</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40-direct|x64">
+ <Configuration>ReleaseVray40-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40|x64">
+ <Configuration>ReleaseVray40</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>shaveVraySh</ProjectName>
+ <ProjectGuid>{67281644-B839-42DE-A013-38725B2DE280}</ProjectGuid>
+ <RootNamespace>shaveVraySh</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)Sh\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(AUTODESK_LOCATION)\Maya2016\vray\vrayplugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(AUTODESK_LOCATION)\Maya2017\vray\vrayplugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">true</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ShaveSh</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">ShaveSh36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">ShaveSh40</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">ShaveSh36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">ShaveSh40</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(AUTODESK_LOCATION)\Maya2011\vray\vrayplugins\shaveSh.dll</OutputFile>
+ <AdditionalLibraryDirectories>..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\include22_win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray22\win64</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY30;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc11</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY40;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc11</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY30;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc11</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY40;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc11</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(AUTODESK_LOCATION)\Maya2012\vray\vrayplugins\shaveSh.dll</OutputFile>
+ <AdditionalLibraryDirectories>..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="shaderMain.cpp" />
+ <ClCompile Include="shaveVrayBaseBSDF.cpp" />
+ <ClCompile Include="shaveVrayBaseBSDFPool.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shaveVrayBaseBSDF.h" />
+ <ClInclude Include="shaveVrayBaseBSDFPool.h" />
+ <ClInclude Include="hairAPI.h" />
+ <ClInclude Include="hairAPIvray.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="shaveVraySh.def" />
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vrayPlug/plugin/shaveVraySh-vs15.sln b/vrayPlug/plugin/shaveVraySh-vs15.sln
new file mode 100644
index 0000000..eb221f5
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySh-vs15.sln
@@ -0,0 +1,30 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaveVraySh", "shaveVraySh-vs15.vcxproj", "{67281644-B839-42DE-A013-38725B2DE280}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ ReleaseVray36|x64 = ReleaseVray36|x64
+ ReleaseVray36-direct|x64 = ReleaseVray36-direct|x64
+ ReleaseVray40|x64 = ReleaseVray40|x64
+ ReleaseVray40-direct|x64 = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {67281644-B839-42DE-A013-38725B2DE280}.Debug|x64.ActiveCfg = Debug|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Debug|x64.Build.0 = Debug|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Release|x64.ActiveCfg = Release|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.Release|x64.Build.0 = Release|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36|x64.ActiveCfg = ReleaseVray36|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray36-direct|x64.ActiveCfg = ReleaseVray36-direct|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40|x64.ActiveCfg = ReleaseVray40|x64
+ {67281644-B839-42DE-A013-38725B2DE280}.ReleaseVray40-direct|x64.ActiveCfg = ReleaseVray40-direct|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vrayPlug/plugin/shaveVraySh-vs15.vcxproj b/vrayPlug/plugin/shaveVraySh-vs15.vcxproj
new file mode 100644
index 0000000..5a35c22
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySh-vs15.vcxproj
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug 2012|x64">
+ <Configuration>Debug 2012</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36-direct|x64">
+ <Configuration>ReleaseVray36-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray36|x64">
+ <Configuration>ReleaseVray36</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40-direct|x64">
+ <Configuration>ReleaseVray40-direct</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseVray40|x64">
+ <Configuration>ReleaseVray40</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>shaveVraySh</ProjectName>
+ <ProjectGuid>{67281644-B839-42DE-A013-38725B2DE280}</ProjectGuid>
+ <RootNamespace>shaveVraySh</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)Sh\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">..\bin\win64\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(AUTODESK_LOCATION)\Maya2018\vray\vrayplugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">$(Platform)\$(Configuration)Sh\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">true</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ShaveSh</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">ShaveSh36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">ShaveSh40</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">ShaveSh36</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">ShaveSh40</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(AUTODESK_LOCATION)\Maya2011\vray\vrayplugins\shaveSh.dll</OutputFile>
+ <AdditionalLibraryDirectories>..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\include22_win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;..\libs\vray22\win64</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY30;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc14</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY40;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc14</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray36-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\3.60.04\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY30;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\3.60.04\lib\win\vc14</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseVray40-direct|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SHAVE_VRAY_SDKS)\4.04.01\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY40;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\lib64;$(SHAVE_VRAY_SDKS)\4.04.01\lib\win\vc14</AdditionalLibraryDirectories>
+ <IgnoreSpecificDefaultLibraries>LIBCMT.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 2012|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\include2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0500;_CRT_SECURE_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;REQUIRE_IOSTREAM;SHAVEVRAYSH_EXPORTS;VRAY20;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>vray.lib;rayserver_s.lib;vutils_s.lib;plugman_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(AUTODESK_LOCATION)\Maya2012\vray\vrayplugins\shaveSh.dll</OutputFile>
+ <AdditionalLibraryDirectories>..\libs\vray2\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ModuleDefinitionFile>shaveVraySh.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="shaderMain.cpp" />
+ <ClCompile Include="shaveVrayBaseBSDF.cpp" />
+ <ClCompile Include="shaveVrayBaseBSDFPool.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shaveVrayBaseBSDF.h" />
+ <ClInclude Include="shaveVrayBaseBSDFPool.h" />
+ <ClInclude Include="hairAPI.h" />
+ <ClInclude Include="hairAPIvray.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="shaveVraySh.def" />
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vrayPlug/plugin/shaveVraySh.def b/vrayPlug/plugin/shaveVraySh.def
new file mode 100644
index 0000000..3444d44
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySh.def
@@ -0,0 +1,9 @@
+LIBRARY "shaveVraySh"
+
+EXPORTS
+
+ CreateShaveBSDFPool @1
+
+SECTIONS
+
+ .data READ WRITE
diff --git a/vrayPlug/plugin/shaveVrayShadeData.cpp b/vrayPlug/plugin/shaveVrayShadeData.cpp
new file mode 100644
index 0000000..2cda157
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayShadeData.cpp
@@ -0,0 +1,268 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "shaveVrayShadeData.h"
+#include "shaveVrayInstance.h"
+#include "shaveVrayStaticVoxelPrim.h"
+#include "shaveVrayMovingVoxelPrim.h"
+
+
+shaveVrayShadeData::shaveVrayShadeData(shaveVrayInstance *instance/*, MayaHairPrimitiveType *hairPrimitive*/)
+ : BaseShadeData(instance)
+{
+}
+
+shaveVrayVoxelPrim* shaveVrayShadeData::getIntersectedPrimitive(const VR::VRayContext &rc) {
+ if (rc.rayresult.primitive) {
+ if (rc.rayresult.primitive->type()==PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE) {
+ VUtils::StaticHairSegmentLine *prim=static_cast<VR::StaticHairSegmentLine*>(rc.rayresult.primitive);
+ return static_cast<shaveVrayStaticVoxelPrim*>(prim->owner->owner);
+ }
+ if (rc.rayresult.primitive->type()==PRIM_TYPE_MOVING_HAIR_SEGMENT_LINE) {
+ VUtils::MovingHairSegmentLine *prim=static_cast<VR::MovingHairSegmentLine*>(rc.rayresult.primitive);
+ return static_cast<shaveVrayMovingVoxelPrim*>(prim->owner->owner);
+ }
+#if defined(VRAY30) || defined(VRAY40)
+ if (rc.rayresult.primitive->type()==PRIM_TYPE_STATIC_HAIR_TREE) {
+ VUtils::StaticHairTreePrimitive *prim=static_cast<VUtils::StaticHairTreePrimitive*>(rc.rayresult.primitive);
+ return static_cast<shaveVrayStaticVoxelPrim*>(prim->owner);
+ }
+ if (rc.rayresult.primitive->type()==PRIM_TYPE_MOVING_HAIR_TREE) {
+ VUtils::MovingHairTreePrimitive *prim=static_cast<VUtils::MovingHairTreePrimitive*>(rc.rayresult.primitive);
+ return static_cast<shaveVrayMovingVoxelPrim*>(prim->owner);
+ }
+#endif
+ }
+ return NULL;
+}
+
+
+VR::Color shaveVrayShadeData::getColor(const VR::VRayContext &rc)
+{
+ shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+ if (voxelPrim) {
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ VR::Color result=VR::Color(0.0f, 1.0f, 0.0f);
+ if (voxelPrim->IsColorConst(strandIdx))
+ voxelPrim->GetRootColor(strandIdx, result);
+ else
+ voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result);
+ return result;
+ }
+ return VR::Color(0.0, 0.0, 0.0);
+}
+
+//VR::Vector shaveVrayShadeData::getVelocity(const VR::VRayContext &rc)
+//{
+// shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+// if (voxelPrim) {
+// int strandIdx=rc.rayresult.faceIndex;
+// int segmentIdx=(int)rc.rayresult.extraf;
+// float segmentOffset=rc.rayresult.bary[2];
+//
+// VR::Vector result=VR::Vector(0.0f, 1.0f, 0.0f);
+// //if (voxelPrim->IsColorConst(strandIdx))
+// // voxelPrim->GetRootColor(strandIdx, result);
+// //else
+// // voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result);
+// return result;
+// }
+// return VR::Vector(0.0, 0.0, 0.0);
+//}
+
+VR::Color shaveVrayShadeData::getIncandescence(const VR::VRayContext &rc)
+{
+ return VR::Color(1.0, 1.0, 1.0); //temp
+ //int pos;
+ //float blend;
+ //getPositionAndBlend(rc, pos, blend);
+ //return hairData.incandescence[pos]*(1.0f-blend) + hairData.incandescence[pos+1]*blend;
+}
+
+VR::Color shaveVrayShadeData::getTransparency(const VR::VRayContext &rc)
+{
+ shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+ if (voxelPrim) {
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ float opacity=1.0f;
+ if (voxelPrim->GetTipFade())
+ opacity=voxelPrim->GetInterpOpacity(segmentIdx, strandIdx, segmentOffset);
+ else
+ opacity=voxelPrim->GetOpacity(strandIdx);
+
+ float t=1.0f-opacity;
+ return VR::Color(t, t, t);
+
+ }
+ return VR::Color(1.0, 1.0, 1.0);
+}
+
+void shaveVrayShadeData::getShadeData(const VR::VRayContext &rc, VR::VRayMayaHairShadeData &result)
+{
+ shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+ if (voxelPrim) {
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ result.hairDirection=voxelPrim->GetHairDir(rc.rayresult.origPoint, segmentIdx, strandIdx, segmentOffset);
+ result.color=VR::Color(0.0f, 1.0f, 0.0f);
+ if (voxelPrim->IsColorConst(strandIdx))
+ voxelPrim->GetRootColor(strandIdx, result.color);
+ else
+ voxelPrim->GetInterpColor(segmentIdx, strandIdx, segmentOffset, result.color);
+
+ float opacity=1.0f;
+ if (voxelPrim->GetTipFade())
+ opacity=voxelPrim->GetInterpOpacity(segmentIdx, strandIdx, segmentOffset);
+ else
+ opacity=voxelPrim->GetOpacity(strandIdx);
+
+ float t=1.0f-opacity;
+ result.transparency=VR::Color(t, t, t);
+ }
+}
+
+float shaveVrayShadeData::getDistanceAlongStrand(const VR::VRayContext &rc) {
+ int primType=rc.rayresult.primitive->type();
+ float k=0.0f;
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+ if (PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE==primType) {
+ VR::StaticHairSegmentLine *seg=static_cast<VR::StaticHairSegmentLine*>(rc.rayresult.primitive);
+ k=seg->getWCoord(segmentOffset);
+ } else if (PRIM_TYPE_MOVING_HAIR_SEGMENT_LINE==primType) {
+ VR::MovingHairSegmentLine *seg=static_cast<VR::MovingHairSegmentLine*>(rc.rayresult.primitive);
+ k=seg->getWCoord(segmentOffset);
+#if defined(VRAY30) || defined(VRAY40)
+ } else if (PRIM_TYPE_STATIC_HAIR_TREE==primType) {
+ VR::StaticHairTreePrimitive *treePrim=static_cast<VR::StaticHairTreePrimitive*>(rc.rayresult.primitive);
+ k=treePrim->getWCoord(strandIdx, segmentIdx, segmentOffset);
+ } else if (PRIM_TYPE_MOVING_HAIR_TREE==primType) {
+ VR::MovingHairTreePrimitive *treePrim=static_cast<VR::MovingHairTreePrimitive*>(rc.rayresult.primitive);
+ k=treePrim->getWCoord(strandIdx, segmentIdx, segmentOffset);
+#endif
+ }
+ return k;
+}
+
+#if defined(VRAY30)
+VR::Transform shaveVrayShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel) {
+ VR::Transform result(0);
+
+ shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+ if (voxelPrim) {
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+ result.offs=voxelPrim->GetUVW(segmentIdx, strandIdx, segmentOffset, channel);
+ }
+
+ return result;
+}
+#elif defined(VRAY40)
+void shaveVrayShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel, VR::ShadeTransform &result) {
+ result.m.makeZero();
+ getLocalUVWCoordinates(rc, channel, result.offs);
+}
+
+void shaveVrayShadeData::getLocalUVWCoordinates(const VR::VRayContext &rc, int channel, VR::ShadeVec &result) {
+ shaveVrayVoxelPrim* voxelPrim=getIntersectedPrimitive(rc);
+ if (voxelPrim) {
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+ result=VR::toShadeVec(voxelPrim->GetUVW(segmentIdx, strandIdx, segmentOffset, channel));
+ }
+}
+
+int shaveVrayShadeData::getLocalUVWTransformByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeTransform &result) {
+ return channelNotFound;
+}
+
+int shaveVrayShadeData::getUVWCoordinatesByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeVec &result) {
+ return channelNotFound;
+}
+
+VR::ShadeVec shaveVrayShadeData::getMapChannelVertexVector(int mapChannelIdx, int vertexIdx) {
+ return VR::ShadeVec(0.0f);
+}
+
+VR::ShadeVec shaveVrayShadeData::getUVWcoords(const VR::VRayContext &rc, int channel) {
+ return getMappedUVWcoords(rc, *this, channel);
+}
+
+void shaveVrayShadeData::getUVWderivs(const VR::VRayContext &rc, int channel, VR::ShadeVec derivs[2]) {
+ getMappedUVWderivs(rc, *this, channel, derivs);
+}
+
+void shaveVrayShadeData::getUVWbases(const VR::VRayContext &rc, int channel, VR::ShadeVec bases[3]) {
+ getMappedUVWbases(rc, *this, channel, bases);
+}
+
+VR::ShadeVec shaveVrayShadeData::getUVWnormal(const VR::VRayContext &rc, int channel) {
+ return getMappedUVWnormal(rc, *this, channel);
+}
+
+#endif
+
+#if defined(VRAY30) || defined(VRAY40)
+
+float shaveVrayShadeData::getRandByStrand(const VR::VRayContext &rc, int seedOffset)
+{
+ int index=getStrandIndex(rc);
+ VR::Random rnd(index+seedOffset);
+ float res=rnd.rnd();
+ return res;
+}
+
+int shaveVrayShadeData::getStrandIndex(const VR::VRayContext &rc)
+{
+ int strandIdx, segmentIdx;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx);
+ return strandIdx;
+}
+
+int shaveVrayShadeData::getSegmentIndexInStrand(const VR::VRayContext &rc)
+{
+ int strandIdx, segmentIdx;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx);
+ return segmentIdx;
+}
+
+void shaveVrayShadeData::getIndexAndBlend(const VR::VRayContext &rc, int &out_index, float &out_blend)
+{
+ out_index = 0;
+ out_blend = 0.0f;
+}
+
+#if VRAY_DLL_VERSION >= 0x36000
+float shaveVrayShadeData::getStrandLength(const VR::VRayContext &rc)
+{
+ shaveVrayVoxelPrim* voxelPrim = getIntersectedPrimitive(rc);
+ if (!voxelPrim) return 0;
+ int strandIdx, segmentIdx;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx);
+ int vStart, vEnd;
+ voxelPrim->_voxel()->GetStrand(strandIdx, vStart, vEnd);
+ VR::Vector prev, next;
+ float length = 0;
+ voxelPrim->_voxel()->GetVert(vStart, prev.x, prev.y, prev.z);
+ for (int i = vStart + 1; i < vEnd; i++) {
+ voxelPrim->_voxel()->GetVert(i, next.x, next.y, next.z);
+ length += VR::length(next - prev);
+ prev = next;
+ }
+ return length;
+}
+#endif
+
+#endif
diff --git a/vrayPlug/plugin/shaveVrayShadeData.h b/vrayPlug/plugin/shaveVrayShadeData.h
new file mode 100644
index 0000000..b85c8aa
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayShadeData.h
@@ -0,0 +1,124 @@
+#ifndef _HAIR_VRAY_SHADE_DATA_H_
+#define _HAIR_VRAY_SHADE_DATA_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+#include "hairprimitives.h"
+#include "rayprimitives.h"
+
+class shaveVrayInstance;
+class shaveVrayVoxelPrim;
+
+class shaveVrayShadeData : public VR::BaseShadeData,
+#if VRAY_DLL_VERSION < 0x31000
+ public VR::VRayMayaHairDataInterface,
+ public VR::VRayFurSamplingInterface,
+#else
+ public VR::VRayHairCommonShadeData,
+#endif
+ public VR::MappedSurface
+{
+#if defined(VRAY30) || defined(VRAY40)
+ VR::HairData *hairData;
+#endif
+ shaveVrayVoxelPrim* getIntersectedPrimitive(const VR::VRayContext &rc);
+public:
+
+ shaveVrayShadeData(shaveVrayInstance *instance /*, MayaHairPrimitiveType *hairPrimitive*/);
+
+ PluginBase* getPlugin(void) VRAY_OVERRIDE
+ {
+ return NULL;
+ }
+ PluginInterface* newInterface(InterfaceID id) VRAY_OVERRIDE
+ {
+#if VRAY_DLL_VERSION < 0x31000
+ if (id==EXT_MAYA_HAIR_DATA)
+ return static_cast<VR::VRayMayaHairDataInterface*>(this);
+ if (id==EXT_VRAY_FUR_SAMPLING)
+ return static_cast<VR::VRayFurSamplingInterface*>(this);
+#else
+ if (id==EXT_VRAY_COMMON_HAIR_SHADE_DATA)
+ return static_cast<VR::VRayHairCommonShadeData*>(this);
+#endif
+ if (id==EXT_MAPPED_SURFACE)
+ return static_cast<VR::MappedSurface*>(this);
+
+ return BaseShadeData::newInterface(id);
+ }
+
+ // From VRayMayaHairDataInterface
+ // From VRayHairCommonShadeData (3.0)
+ VR::Color getColor(const VR::VRayContext &rc) VRAY_OVERRIDE;
+ VR::Color getIncandescence(const VR::VRayContext &rc) VRAY_OVERRIDE;
+ VR::Color getTransparency(const VR::VRayContext &rc) VRAY_OVERRIDE;
+ void getShadeData(const VR::VRayContext &rc, VR::VRayMayaHairShadeData &result) VRAY_OVERRIDE;
+#if defined(VRAY30) || defined(VRAY40)
+ float getRandByStrand(const VR::VRayContext &rc, int seedOffset) VRAY_OVERRIDE;
+
+ int getStrandIndex(const VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ int getSegmentIndexInStrand(const VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ void getIndexAndBlend(const VR::VRayContext &rc, int &out_index, float &out_blend) VRAY_OVERRIDE;
+# if VRAY_DLL_VERSION >= 0x36000
+ float getStrandLength(const VR::VRayContext &rc) VRAY_OVERRIDE;
+# endif
+
+#endif
+
+ // From VRayFurSamplingInterface
+ float getDistanceAlongStrand(const VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ // From MappedSurface
+#if defined(VRAY30)
+ VR::Transform getLocalUVWTransform(const VR::VRayContext &rc, int channel) VRAY_OVERRIDE;
+#elif defined(VRAY40)
+ void getLocalUVWTransform(const VR::VRayContext &rc, int channel, VR::ShadeTransform &result) override;
+ void getLocalUVWCoordinates(const VR::VRayContext &rc, int channel, VR::ShadeVec &result) override;
+ int getLocalUVWTransformByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeTransform &result) override;
+ int getUVWCoordinatesByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeVec &result) override;
+ VR::ShadeVec getMapChannelVertexVector(int mapChannelIdx, int vertexIdx) override;
+ VR::ShadeVec getUVWcoords(const VR::VRayContext &vri, int channel) override;
+ void getUVWderivs(const VR::VRayContext &vri, int channel, VR::ShadeVec derivs[2]) override;
+ void getUVWbases(const VR::VRayContext &vri, int channel, VR::ShadeVec bases[3]) override;
+ VR::ShadeVec getUVWnormal(const VR::VRayContext &vri, int channel) override;
+#endif
+};
+
+/*
+ * Get strand, segment index and offset within segment from ray context.
+ */
+static inline void shaveVrayGetHairParams(const VR::VRayContext &rc, int &out_strand, int &out_segment, float &out_offset) {
+#if defined(VRAY30) || defined(VRAY40)
+ out_strand = rc.rayresult.extra_int[1];
+ out_segment = rc.rayresult.faceIndex;
+ out_offset = rc.rayresult.bary[0];
+#else
+ out_strand = rc.rayresult.faceIndex;
+ out_segment = (int)rc.rayresult.extraf;
+ out_offset = rc.rayresult.bary[2];
+#endif
+}
+
+/*
+ * Get strand and segment index from ray context.
+ */
+static inline void shaveVrayGetHairParams(const VR::VRayContext &rc, int &out_strand, int &out_segment) {
+#if defined(VRAY30) || defined(VRAY40)
+ out_strand = rc.rayresult.extra_int[1];
+ out_segment = rc.rayresult.faceIndex;
+#else
+ out_strand = rc.rayresult.faceIndex;
+ out_segment = (int)rc.rayresult.extraf;
+#endif
+}
+
+#endif
diff --git a/vrayPlug/plugin/shaveVrayShadeInstance.h b/vrayPlug/plugin/shaveVrayShadeInstance.h
new file mode 100644
index 0000000..22f825d
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayShadeInstance.h
@@ -0,0 +1,64 @@
+#ifndef _HAIR_VR_SHADE_INSTANCE_H_
+#define _HAIR_VR_SHADE_INSTANCE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include <vrayinterface.h>
+#include <geometryclasses.h>
+#include "vray3_compat.h"
+#include "shaveVrayVoxelPrim.h"
+
+//class shaveVrayVoxelPrim;
+
+class shaveVrayShadeInstance: public VR::VRayShadeInstance, VR::ObjectShadeInstance {
+
+ shaveVrayVoxelPrim *hairPrim;
+public:
+ shaveVrayShadeInstance(shaveVrayVoxelPrim *p):hairPrim(p){}
+
+ PluginInterface* newInterface(InterfaceID id) VRAY_OVERRIDE {
+ if (id == EXT_OBJECT_SHADE_INSTANCE) return static_cast<VR::ObjectShadeInstance*>(this);
+ return NULL;
+ }
+ PluginBase* getPlugin(void) VRAY_OVERRIDE {return this;}
+
+ // From ObjectShadeInstance
+ VR::ShadeVec getBasePtObj(const VR::VRayContext &rc) VRAY_OVERRIDE {return rc.rayresult.wpoint;}
+ VR::ShadeVec worldToObjectVec(const VR::VRayContext &rc, const VR::ShadeVec &vec) VRAY_OVERRIDE {
+ (void)rc; (void)vec;
+ return /*(rc.rayparams.currentPass != RPASS_GI && rc.rayparams.currentPass != RPASS_LIGHTMAP) ? vec :*/ VR::ShadeVec(1.0f,0.0f,0.0f);}
+ VR::ShadeVec worldToObjectPt(const VR::VRayContext &rc, const VR::ShadeVec &pt) VRAY_OVERRIDE {
+ (void)rc; (void)pt;
+ return /*(rc.rayparams.currentPass != RPASS_GI && rc.rayparams.currentPass != RPASS_LIGHTMAP) ? pt :*/ VR::ShadeVec(0.0f,0.0f,0.0f);}
+ VR::ShadeVec objectToWorldVec(const VR::VRayContext &rc, const VR::ShadeVec &vec) VRAY_OVERRIDE {
+ (void)rc; (void)vec;
+ return /*(rc.rayparams.currentPass != RPASS_GI && rc.rayparams.currentPass != RPASS_LIGHTMAP) ? vec :*/ VR::ShadeVec(1.0f,0.0f,0.0f);}
+ VR::ShadeVec objectToWorldPt(const VR::VRayContext &rc, const VR::ShadeVec &pt) VRAY_OVERRIDE {
+ (void)rc; (void)pt;
+ return /*(rc.rayparams.currentPass != RPASS_GI && rc.rayparams.currentPass != RPASS_LIGHTMAP) ? pt :*/ VR::ShadeVec(0.0f,0.0f,0.0f);}
+#if defined(VRAY30)
+ VR::TracePoint getShadowPt(const VR::VRayContext &rc) VRAY_OVERRIDE{return rc.rayresult.wpoint; }
+#elif defined(VRAY40)
+ VR::ShadeVec getShadowPt(const VR::VRayContext &rc) VRAY_OVERRIDE{return rc.rayresult.wpoint; }
+#endif
+ VR::ShadeVec getVelocity(const VR::VRayContext &rc) VRAY_OVERRIDE
+ {
+ const IHairVoxel* hair=hairPrim->GetVoxel();
+
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ int fs, fe;
+ hair->GetFace(strandIdx, fs, fe);
+ int vert_idx = fs + segmentIdx;
+
+ VR::ShadeVec ve0, ve1;
+ GetVelocity(hair, vert_idx, ve0);
+ GetVelocity(hair, vert_idx + 1, ve1);
+ return VR::interpolate(segmentOffset, ve0, ve1);
+ }
+};
+#endif
diff --git a/vrayPlug/plugin/shaveVrayShadeable.cpp b/vrayPlug/plugin/shaveVrayShadeable.cpp
new file mode 100644
index 0000000..dd14079
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayShadeable.cpp
@@ -0,0 +1,258 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayShadeable.cpp -- implementation file ( HairVrShadeable.cpp )
+
+ DESCRIPTION: Used to shade a surface
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 21-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayShadeable.h"
+#include "hairAPIvray.h"
+#include "shaveVrayPlugin.h"
+#include "shaveVrayInstance.h"
+
+#if (defined WIN32) ||(defined LINUX)
+;
+#else
+#include "shaveVrayBaseBSDFPool.h" // I did not split it for osx yet
+#endif
+
+#include "shaveVraySharedFunctions.h"
+
+
+
+
+shaveVrayShadeable::shaveVrayShadeable(shaveVrayVoxelPrim *hair)
+{
+ _prim() = hair;
+#ifdef USE_WHITE_BRDF
+ ;
+#else
+ _bsdfPool() = NULL;
+
+#if (defined WIN32) ||(defined LINUX)
+ //_bsdfPool() = new shaveVrayBaseBSDFPool();
+ if(CreateShaveBSDFPool != NULL)
+ {
+ _bsdfPool() = CreateShaveBSDFPool();
+ }
+ if(!bsdfPool())
+ {
+ LOGMSG("SHADE","shaveVrayShadeable: can not create BSDF pool.");
+ }
+#else //osx
+ _bsdfPool() = new shaveVrayBaseBSDFPool();
+#endif
+#endif
+}
+
+shaveVrayShadeable::~shaveVrayShadeable()
+{
+ freeBSDFpool();
+}
+/*
+| from Shadeable
+*/
+void shaveVrayShadeable::shade(VR::VRayContext &rc)
+{
+ //no trace
+ //if(rc.rayparams.diffuseLevel > 1)
+ //{
+ // rc.mtlresult.makeOpaque();
+ // return;
+ //}
+
+ BSDFShadeable::shade(rc);
+
+ //////just a test - no trace ////
+ //rc.mtlresult.alpha.r = 0.0f;
+ //rc.mtlresult.alpha.g = 0.0f;
+ //rc.mtlresult.alpha.b = 0.0f;
+
+ //rc.mtlresult.transp.r = 0.f;
+ //rc.mtlresult.transp.g = 0.f;
+ //rc.mtlresult.transp.b = 0.f;
+
+ //rc.mtlresult.alphaTransp.r = 0.0f;
+ //rc.mtlresult.alphaTransp.g = 0.0f;
+ //rc.mtlresult.alphaTransp.b = 0.0f;
+
+ //int strandIdx = rc.rayresult.faceIndex;
+ //VR::Color diffCol = VR::Color(0.0f, 1.0f, 0.0f); //just green to see if somthing goes wrong
+
+ //int segmentIdx=(int) rc.rayresult.extraf;
+ //float segmentOffset=rc.rayresult.bary[2];
+
+ //if(prim()->IsColorConst(strandIdx))
+ // prim()->GetRootColor(strandIdx,diffCol);
+ //else
+ // prim()->GetInterpColor(segmentIdx, strandIdx, segmentOffset, diffCol);
+
+ //rc.mtlresult.color = diffCol;
+ //////////////////////////////
+
+#ifdef USE_WHITE_BRDF
+ VR::Color diffCol = VR::Color(0.0f, 1.0f, 0.0f); //just green to see if somthing goes wrong
+
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ if(prim()->IsColorConst(strandIdx))
+ prim()->GetRootColor(strandIdx,diffCol);
+ else
+ prim()->GetInterpColor(segmentIdx, strandIdx, segmentOffset, diffCol);
+
+ rc.mtlresult.color *= diffCol;
+#endif
+}
+/*
+| from Shadeable
+*/
+tchar* shaveVrayShadeable::getName(VR::VRayContext &rc)
+{
+ return const_cast<tchar*>("shaveVrayShadeable");
+}
+
+VR::BSDFSampler* shaveVrayShadeable::newBSDF (const VR::VRayContext &rc, VR::BSDFFlags flags)
+{
+#ifdef USE_WHITE_BRDF
+ VR::WhiteBRDF *bsdf = _bsdfPool().newBRDF(rc);
+ return bsdf;
+#else
+ //shaveVrayBaseBSDF* bsdf = _bsdfPool().newBRDF(rc);
+ IShaveVrayBSDF* bsdf = NULL;
+ if(bsdfPool())
+ {
+ bsdf =_bsdfPool()->newBRDF(rc);
+ }
+ if (!bsdf)
+ return NULL;
+
+ VR::Color diffCol = VR::Color(0.0f, 1.0f, 0.0f); //just green to see if somthing goes wrong
+
+ int strandIdx, segmentIdx;
+ float segmentOffset;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx, segmentOffset);
+
+ if(prim()->IsColorConst(strandIdx))
+ prim()->GetRootColor(strandIdx,diffCol);
+ else
+ prim()->GetInterpColor(segmentIdx, strandIdx, segmentOffset, diffCol);
+
+ VR::Color specCol = VR::Color(1.0f, 1.0f, 1.0f);
+
+ float opacity = 1.0f;
+ //hair is opaque for GI prepass steps to speedup computations -- 08-11-2010
+ if(rc.rayparams.currentPass != RPASS_GI)
+ if(rc.rayparams.currentPass != RPASS_LIGHTMAP)
+ {
+ if(prim()->GetTipFade())
+ opacity = prim()->GetInterpOpacity(segmentIdx, strandIdx, segmentOffset);
+ else
+ opacity = prim()->GetOpacity(strandIdx);
+ }
+ //transparency
+ float t=1.0f-opacity;
+ VR::Color trsp = VR::Color(t, t, t);
+
+ //ambient color [not used yet]
+ VR::Color ambientCol = prim()->GetAmbient();
+
+ //abient/diffuse factor
+ float ambDiff = prim()->GetAmbDiff(strandIdx);
+
+ //glossines
+ float gloss = prim()->GetGlossiness(strandIdx);
+
+ float splvl = prim()->GetSpecLevel(strandIdx);
+
+ //specular tints
+ VR::Color spCol = prim()->GetSpecTint();
+ VR::Color spCol2= prim()->GetSpecTint2();
+
+// printf("spec_tint %f %f %f \n",spCol.r, spCol.g, spCol.b);
+// printf("spec_tint2 %f %f %f \n",spCol2.r, spCol2.g, spCol2.b);
+
+#if defined(VRAY30) || defined(VRAY40)
+ VR::ShadeVec hairDir=prim()->getHairDir(rc);
+#else
+ VR::ShadeVec hairDir=prim()->GetHairDir(rc.rayresult.origPoint, segmentIdx, strandIdx, segmentOffset);
+#endif
+
+ shaveVrayInstance* inst = prim()->GetInstance();
+
+ //printf("inst get selfShadow %f\n",inst->GetSelfShadow());fflush(stdout);
+ bsdf->init(rc,specCol,diffCol,ambientCol,spCol,spCol2,ambDiff,splvl,gloss,0,trsp, hairDir, t,
+ inst->GetCameraVisibility(),
+ inst->GetReflVisibility(),
+ inst->GetRefrlVisibility(),
+ inst->GetLightVisibility(),
+ inst->GetGiVisibility(),
+ inst->GetSelfShadow(),
+ inst->GetRecvShadow());
+
+ return bsdf;
+#endif
+}
+
+void shaveVrayShadeable::deleteBSDF(const VR::VRayContext &rc, VR::BSDFSampler *bsdf)
+{
+ if(!bsdf)
+ return;
+#ifdef USE_WHITE_BRDF
+ VR::WhiteBRDF *dbsdf = static_cast<VR::/*DiffuseBRDF*/WhiteBRDF*>(bsdf);
+ _bsdfPool().deleteBRDF(rc, dbsdf);
+#else
+ //shaveVrayBaseBSDF* dbsdf = static_cast<shaveVrayBaseBSDF*>(bsdf);
+ //_bsdfPool().deleteBRDF(rc, dbsdf);
+
+ IShaveVrayBSDF* dbsdf = static_cast<IShaveVrayBSDF*>(bsdf);
+ if(bsdfPool())
+ {
+ _bsdfPool()->deleteBRDF(rc, dbsdf);
+ }
+#endif
+}
+
+#if defined(VRAY40)
+int shaveVrayShadeable::getBSDFFlags()
+{
+ return VR::bsdfFlag_none;
+}
+#endif
+
+void shaveVrayShadeable::initBSDFpool(VR::VRayCore *vray)
+{
+#ifdef USE_WHITE_BRDF
+ const VR::VRaySequenceData &sdata=vray->getSequenceData();
+ _bsdfPool().init(sdata.maxRenderThreads);
+#else
+ if(bsdfPool())
+ {
+ _bsdfPool()->init(vray);
+ }
+#endif
+}
+
+void shaveVrayShadeable::freeBSDFpool()
+{
+#ifdef USE_WHITE_BRDF
+ _bsdfPool().freeMem();
+#else
+ if(bsdfPool())
+ {
+ _bsdfPool()->freeMem();
+ }
+#endif
+}
diff --git a/vrayPlug/plugin/shaveVrayShadeable.h b/vrayPlug/plugin/shaveVrayShadeable.h
new file mode 100644
index 0000000..f84ee73
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayShadeable.h
@@ -0,0 +1,109 @@
+#ifndef _HAIR_VR_SHADEABLE_H_
+#define _HAIR_VR_SHADEABLE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayShadeable.h ( was HairVrShadeable.h )
+
+ DESCRIPTION: Used by VRay to shade a surface
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 21-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+//#include <vraybase.h>
+//#include <vectorbase.h>
+//#include <vrayinterface.h>
+//#include <vrayplugins.h>
+//#include <vraygeom.h>
+//#include <brdfs.h>
+//#include <brdfpool.h>
+
+#include "hairAPIvrayutil.h"
+#include "hairAPIvray.h"
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+#include "brdfs.h"
+#include "brdfpool.h"
+
+#include "shaveVrayVoxelPrim.h"
+#include "shaveVrayBaseBSDF.h"
+
+//#define USE_WHITE_BRDF
+
+class shaveVrayShadeable : public /*VR::Shadeable*/ VR::BSDFShadeable {
+public:
+ shaveVrayShadeable(shaveVrayVoxelPrim* hair);
+ ~shaveVrayShadeable();
+ /*
+ | from Shadeable
+ */
+ // This is called to shade the intersection in the rayresult member of the given context.
+ void shade(VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ //Returns the name of the shadeable; used to print warnings if any shading errors occur.
+ tchar* getName(VR::VRayContext &rc) VRAY_OVERRIDE;
+
+ /*
+ |
+ */
+ VR::BSDFSampler* newBSDF (const VR::VRayContext &rc, VR::BSDFFlags flags) VRAY_OVERRIDE;
+
+ void deleteBSDF(const VR::VRayContext &rc, VR::BSDFSampler *bsdf) VRAY_OVERRIDE;
+
+#if defined VRAY40
+ int getBSDFFlags() VRAY_OVERRIDE;
+#endif
+
+ /*
+ | own
+ */
+ void initBSDFpool(VR::VRayCore *vray);
+
+ void freeBSDFpool();
+
+protected:
+ //const member access
+#ifdef USE_WHITE_BRDF
+ inline const VR::BRDFPool<VR::WhiteBRDF>& bsdfPool() const {return m_bsdfPool;}
+#else
+ //inline const VR::BRDFPool<shaveVrayBaseBSDF>& bsdfPool() const {return m_bsdfPool;}
+ inline IShaveBSDFPool* bsdfPool() {return m_bsdfPool;}
+#endif
+ inline shaveVrayVoxelPrim* prim() const {return m_prim;}
+ //inline IHairVoxel* prim() const {return m_prim;}
+
+ //const member access
+#ifdef USE_WHITE_BRDF
+ inline VR::BRDFPool<VR::WhiteBRDF>& _bsdfPool() {return m_bsdfPool;}
+#else
+ //inline VR::BRDFPool<shaveVrayBaseBSDF>& _bsdfPool() {return m_bsdfPool;}
+ inline IShaveBSDFPool*& _bsdfPool() {return m_bsdfPool;}
+#endif
+ inline shaveVrayVoxelPrim*& _prim() {return m_prim;}
+ //inline IHairVoxel*& _prim() {return m_prim;}
+
+protected:
+#ifdef USE_WHITE_BRDF
+ VR::BRDFPool<VR::WhiteBRDF> m_bsdfPool;
+#else
+ //VR::BRDFPool<shaveVrayBaseBSDF> m_bsdfPool;
+ IShaveBSDFPool* m_bsdfPool;
+#endif
+ shaveVrayVoxelPrim* m_prim;
+ //IHairVoxel* m_prim;
+};
+
+#endif //end of_HAIR_VR_SHADEABLE_H_
diff --git a/vrayPlug/plugin/shaveVraySharedFunctions.cpp b/vrayPlug/plugin/shaveVraySharedFunctions.cpp
new file mode 100644
index 0000000..c33a27e
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySharedFunctions.cpp
@@ -0,0 +1,483 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVraySharedFunctions.cpp
+
+ DESCRIPTION: Various shared functions
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 21-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVraySharedFunctions.h"
+#include "shaveVrayPlugin.h"
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef LINUX
+#include <unistd.h>
+#endif
+
+
+#ifdef WIN32
+HINSTANCE hInstance = NULL;
+static HINSTANCE lib_handle = NULL;
+#else
+#include <dlfcn.h>
+#include <unistd.h>
+static void *lib_handle = NULL;
+#endif
+
+PFNCREATEBSDFPOOL CreateShaveBSDFPool = NULL;
+
+static char separator =
+#ifdef WIN32
+';'
+#else
+':'
+#endif
+;
+
+int GetNumPaths(const char* multi)
+{
+ unsigned int len = (unsigned int)strlen(multi);
+ if(len == 0)
+ return 0;
+
+ int n = 1;
+ for(int i = 0; i < len; i++)
+ if(multi[i] == separator)
+ n++;
+
+ return n;
+}
+
+bool GetPath(const char* multi, int idx, char* path)
+{
+ unsigned int len = (unsigned int)strlen(multi);
+ if(len == 0)
+ return false;
+
+ assert(idx >= 0);
+
+ int start = 0;
+ int end = 0;
+ if(idx == 0)
+ {
+ bool found = false;
+ for(int i = 1; i < len; i++)
+ {
+ if(multi[i] == separator)
+ {
+ end = i-1;
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ end = len-1;
+
+ int j = 0;
+ for(int i = start; i <= end; i++)
+ {
+ path[j] = multi[i];
+ j++;
+ }
+ return true;
+
+ }
+ else
+ {
+ bool found = false;
+ int n = 0;
+ for(int i = 0; i < len; i++)
+ {
+ if(multi[i] == separator)
+ {
+ n++;
+ if(n == idx)
+ {
+ if(i+1 < len)
+ {
+ start = i+1;
+ found = true;
+ }
+ break;
+ }
+ }
+ }
+ if(found)
+ {
+ for(int i = start; i < len; i++)
+ {
+ if(multi[i] == separator)
+ {
+ end = i-1;
+ break;
+ }
+ }
+ if(end == 0)
+ end = len-1;
+
+ if(end > start)
+ {
+ int j = 0;
+ for(int i = start; i <= end; i++)
+ {
+ path[j] = multi[i];
+ j++;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool LoadShaveBSDFPoolLib(const char* libPath)
+{
+ LOGMSGS("SHADE","LoadShaveBSDFPoolLib from",libPath);
+#if defined(WIN32)
+# ifdef VRAY_DUAL
+# ifdef VRAY30
+# if VRAY_DLL_VERSION < 0x31000
+ const char* dllName = "shaveSh30.dll";
+# elif VRAY_DLL_VERSION < 0x36000
+ const char* dllName = "shaveSh31.dll";
+# else
+ const char* dllName = "shaveSh36.dll";
+# endif
+# elif defined(VRAY40)
+ const char* dllName = "shaveSh40.dll";
+# else
+ const char* dllName = "shaveSh.dll";
+# endif
+# else
+ char* dllName = "shaveSh.dll";
+# endif
+
+ if(!lib_handle)
+ {
+ //look up the paths passed from maya
+ bool found = false;
+ char libname[MAX_PATH]= {'\0'};
+ if(libPath != NULL && strlen(libPath) > 1)
+ {
+ //parse multiple paths
+ int npaths = GetNumPaths(libPath);
+ for(int i = 0; i < npaths; i++)
+ {
+ char libname1[MAX_PATH]= {'\0'};
+ char libPath1[MAX_PATH]= {'\0'};
+ if(GetPath(libPath,i,libPath1))
+ {
+ LOGMSGI("SHADE","File 1 :",i);
+
+ sprintf(libname1,"%s/%s",libPath1,dllName);
+
+ //check file existance
+ struct stat buf;
+ int result = stat( libname1, &buf );
+ if( result != 0 )
+ {
+ LOGMSGS("SHADE",libname1,"not found or can not be opened.");
+ }
+ else
+ {
+ LOGMSGS("SHADE","Found",libname1);
+ strcpy(libname,libname1);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ //look into mayaroot/vray/plugins
+ if(!found)
+ {
+ char libname1[MAX_PATH]= {'\0'};
+ char to[MAX_PATH] = {'\0'};
+ char path[MAX_PATH] = {'\0'};
+ if( GetModuleFileName(hInstance, path, MAX_PATH ) )
+ {
+ char drive[6];
+ char dir[MAX_PATH];
+ char file[100];
+ char ext[6];
+
+ errno_t err = _splitpath_s(path,drive,6,dir,MAX_PATH,file,100,ext,6);
+ if(err == 0)
+ {
+ sprintf(to,"%s%s",drive,dir);
+ }
+ }
+ sprintf(libname1,"%s%s",to,dllName);
+#ifdef _DEBUG
+ fprintf(stdout,"LoadShaveBSDFPoolLib: load %s\n",libname);fflush(stdout);
+#endif
+ //check file existance
+ struct stat buf;
+ int result = stat( libname1, &buf );
+ LOGMSG("SHADE","File 2");
+ if( result != 0 )
+ {
+ LOGMSGS("SHADE",libname1,"not found or can not be opened.");
+ }
+ else
+ {
+ LOGMSGS("SHADE","Found",libname1);
+ strcpy(libname,libname1);
+ found = true;
+ }
+ }
+ if(!found) //standalone
+ {
+ char libname1[MAX_PATH]= {'\0'};
+#ifdef _WIN64
+ char* libPath = getenv("VRAY_PLUGINS_x64");
+#else
+ char* libPath = getenv("VRAY_PLUGINS_x86");
+#endif
+ if(libPath && strlen(libPath) > 0)
+ {
+ //parse multiple paths
+ int npaths = GetNumPaths(libPath);
+ for(int i = 0; i < npaths; i++)
+ {
+ char libPath1[MAX_PATH]= {'\0'};
+ char libname1[MAX_PATH]= {'\0'};
+ if(GetPath(libPath,i,libPath1))
+ {
+ sprintf(libname1,"%s/%s",libPath1,dllName);
+
+ LOGMSGI("SHADE","File 3 :",i);
+
+ //check file existance
+ struct stat buf;
+ int result = stat( libname1, &buf );
+ if( result != 0 )
+ {
+ LOGMSGS("SHADE",libname1,"not found or can not be opened.");
+ }
+ else
+ {
+ LOGMSGS("SHADE","Found",libname1);
+ strcpy(libname,libname1);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ fflush(stdout);
+ if(!found)
+ {
+ //do not specify path excplicitly let system find it in libdirs
+ sprintf(libname,"%s",dllName);
+ }
+ lib_handle = LoadLibrary(libname);
+ if (!lib_handle)
+ {
+ int err = GetLastError();
+ LOGMSGI("SHADE","LoadShaveBSDFPoolLib: can not load shaveSh**.dll, error ",err);
+ return false;
+ }
+ CreateShaveBSDFPool = (PFNCREATEBSDFPOOL)GetProcAddress(lib_handle, "CreateShaveBSDFPool");
+ if(CreateShaveBSDFPool == NULL)
+ {
+ int err = GetLastError();
+ LOGMSGI("SHADE","LoadShaveBSDFPoolLib: can not load 'CreateShaveBSDFPool' function, error ",err);
+ return false;
+ }
+
+
+ }
+#elif defined(LINUX)
+# ifdef VRAY_DUAL
+# ifdef VRAY30
+# if VRAY_DLL_VERSION < 0x31000
+ const char* soName = "ShaveSh30.so";
+# elif VRAY_DLL_VERSION < 0x36000
+ const char* soName = "ShaveSh31.so";
+# else
+ const char* soName = "ShaveSh36.so";
+# endif
+# elif defined(VRAY40)
+ const char* soName = "ShaveSh40.so";
+# else
+ const char* soName = "ShaveSh.so";
+# endif
+# else
+ const char* soName = "ShaveSh.so";
+# endif
+
+ if(!lib_handle)
+ {
+ bool found = false;
+ char libname[MAX_PATH]= {'\0'};
+ if(libPath != NULL && strlen(libPath) > 1)
+ {
+ //parse multiple paths
+ int npaths = GetNumPaths(libPath);
+ for(int i = 0; i < npaths; i++)
+ {
+ char libname1[MAX_PATH]= {'\0'};
+ char libPath1[MAX_PATH]= {'\0'};
+ if(GetPath(libPath,i,libPath1))
+ {
+ sprintf(libname1,"%s/%s",libPath1,soName);
+
+ //check file existance
+ struct stat buf;
+ int result = stat( libname1, &buf );
+ if( result != 0 )
+ fprintf(stdout,"File %s (1:%i) \nnot found or can not be opened.\n", libname1,i);
+ else
+ {
+ fprintf(stdout,"Found %s (1:%i).\n", libname1,i);
+ strcpy(libname,libname1);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ if(!found)
+ {
+ char id[526] = {'\0'};
+ char path[526] = {'\0'};
+
+ pid_t pid = getpid();
+ sprintf(id, "/proc/%d/exe", getpid());
+ readlink(id, path, 526);
+#ifdef _DEBUG
+ fprintf(stdout,"pid: %d bin path: %s \n",pid,path);
+#endif
+ char* ptr = strstr(path,"bin");
+ if(ptr)
+ {
+ int pos = (ptr - path);
+ int len = (int)strlen(path);
+ for(int i = pos; i < len; i++)
+ path[i] = '\0';
+
+ strcat(path,"vray/vrayplugins/");
+ strcat(path,soName);
+ }
+ else
+ {
+ fprintf(stdout,"LoadShaveBSDFPoolLib: can not find %s dir (%s).\n",soName,path);fflush(stdout);
+ return false;
+ }
+ struct stat buf;
+ int result = stat( path, &buf );
+ if( result != 0 )
+ fprintf(stdout,"File %s (2) not found in \n%s \nor can not be opened.\n",soName, path);
+ else
+ {
+ fprintf(stdout,"File %s (2) is found in \n %s.\n",soName, path);
+ strcpy(libname,path);
+ found = true;
+ }
+ }
+ if(!found) //standalone vray
+ {
+ char libname1[MAX_PATH]= {'\0'};
+#ifdef Bits64_
+ char* libPath = getenv("VRAY_PLUGINS_x64");
+#else
+ char* libPath = getenv("VRAY_PLUGINS_x86");
+#endif
+ if(libPath)
+ {
+ //parse multiple paths
+ int npaths = GetNumPaths(libPath);
+ for(int i = 0; i < npaths; i++)
+ {
+ char libname1[MAX_PATH]= {'\0'};
+ char libPath1[MAX_PATH]= {'\0'};
+ if(GetPath(libPath,i,libPath1))
+ {
+ sprintf(libname1,"%s/%s",libPath1,soName);
+
+ //check file existance
+ struct stat buf;
+ int result = stat( libname1, &buf );
+ if( result != 0 )
+ fprintf(stdout,"File %s (3:%i) \nnot found or can not be opened.\n", libname1,i);
+ else
+ {
+ fprintf(stdout,"Found %s (3:%i).\n", libname1,i);
+ strcpy(libname,libname1);
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(!found)
+ {
+ //do not specify path excplicitly let system find it in libdirs
+ sprintf(libname,"%s",soName);
+ }
+ lib_handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
+ if (!lib_handle)
+ {
+ printf("LoadShaveBSDFPoolLib: can not load %s\n",soName);
+ char* errstr = dlerror();
+ if (errstr != NULL)
+ fprintf(stdout,"A dynamic linking error occurred: (%s).\n", errstr);
+ fflush(stdout);
+ return false;
+ }
+ CreateShaveBSDFPool = (PFNCREATEBSDFPOOL)dlsym(lib_handle, "CreateShaveBSDFPool");
+ const char* dlsym_error = dlerror();
+ if (dlsym_error || CreateShaveBSDFPool == NULL)
+ {
+ fprintf(stdout,"LoadShaveBSDFPoolLib: can not load 'CreateShaveBSDFPool' function (%s).\n",dlsym_error);fflush(stdout);
+ return false;
+ }
+
+ }
+#else // osx
+ // For MacOS/OS X CreateShaveBSDFPool() is built directly into libvray_Shave*.so. There's
+ // no separate lib to load.
+#endif
+ return true;
+}
+
+void UnLoadShaveBSDFPoolLib()
+{
+#if defined(WIN32) || defined(LINUX)
+ if(lib_handle)
+ {
+#ifdef WIN32
+ FreeLibrary(lib_handle);
+#else
+ dlclose(lib_handle);
+#endif
+ }
+ CreateShaveBSDFPool = NULL;
+ lib_handle = NULL;
+#else // osx
+ // For MacOS/OS X CreateShaveBSDFPool() is built directly into libvray_Shave*.so. There's
+ // no separate lib to unload.
+#endif
+}
+
+
+
+
diff --git a/vrayPlug/plugin/shaveVraySharedFunctions.h b/vrayPlug/plugin/shaveVraySharedFunctions.h
new file mode 100644
index 0000000..920e45a
--- /dev/null
+++ b/vrayPlug/plugin/shaveVraySharedFunctions.h
@@ -0,0 +1,61 @@
+#ifndef _HAIR_VR_PRIM_SHARED_FUCTIONS_H_
+#define _HAIR_VR_PRIM_SHARED_FUCTIONS_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVraySharedFunctions.h
+
+ DESCRIPTION: Various shared functions
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 21-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include <vraybase.h>
+#include "hairAPIvray.h"
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the HAIRVRAY_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// SHAVEVRAYSH_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef WIN32
+#ifdef HAIRVRAY_EXPORTS
+#define HAIRVRAY_API __declspec(dllexport)
+#else
+#define HAIRVRAY_API __declspec(dllimport)
+#endif
+#else
+#define HAIRVRAY_API
+#endif
+
+#ifdef WIN32
+extern HINSTANCE hInstance;
+#endif
+
+extern PFNCREATEBSDFPOOL CreateShaveBSDFPool;
+
+bool LoadShaveBSDFPoolLib(const char* libPath = NULL);
+
+void UnLoadShaveBSDFPoolLib();
+
+inline void GenOrthVectors(const VR::Vector& in, VR::Vector& u, VR::Vector& v)
+{
+ u = (in.x != 0.0f || in.y != 0.0f) ?
+ normalize(VR::Vector(-in.y, in.x, 0.0f)) :
+ VR::Vector(1.0f, 0.0f, 0.0f);
+
+ v = normalize(in^u);
+}
+
+
+#endif //end of_HAIR_VR_PRIM_SHARED_FUCTIONS_H_
diff --git a/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.cpp
new file mode 100644
index 0000000..9c07d39
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.cpp
@@ -0,0 +1,352 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayStaticTriVoxelPrim.cpp -- iplementation file
+
+ DESCRIPTION: Static (non motion blurred) instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayStaticTriVoxelPrim.h"
+#include "shaveVrayInstanceI.h"
+#include "misc_ray.h"
+
+shaveVrayStaticTriVoxelPrim::shaveVrayStaticTriVoxelPrim(
+ IHairVoxel* vox,
+ VR::VRayCore *vray,
+ shaveVrayInstanceI *inst):
+ shaveVrayTriVoxelPrim(vox,vray,inst)
+{
+ _firstid() = -1;
+ _tris() = NULL;
+
+ //if(shdata())
+ //{
+ // ((shaveVrayTriShadeData*)shdata())->init(inst->GetItm0());
+ //}
+
+}
+
+shaveVrayStaticTriVoxelPrim::~shaveVrayStaticTriVoxelPrim()
+{
+}
+
+/*
+| from StaticPrimitive
+*/
+void shaveVrayStaticTriVoxelPrim::getBBox (VR::StaticBox &bbox)
+{
+ //DebugPrint("PRIM> shaveVrayStaticTriVoxelPrim::getBBox ");
+
+ if(voxel())
+ {
+ VERT pmin;
+ VERT pmax;
+ voxel()->GetBbox(pmin,pmax);
+
+ bbox.pmin.x = pmin.x;
+ bbox.pmin.y = pmin.y;
+ bbox.pmin.z = pmin.z;
+
+ bbox.pmax.x = pmax.x;
+ bbox.pmax.y = pmax.y;
+ bbox.pmax.z = pmax.z;
+
+ /*DebugPrint("[%f %f %f][%f %f %f]\n",
+ bbox.pmin.x, bbox.pmin.y, bbox.pmin.z,
+ bbox.pmax.x, bbox.pmax.y, bbox.pmax.z);*/
+
+ VR::Vector scnoffs = VR::toVector(sceneOffset());
+ bbox.pmin -= scnoffs;
+ bbox.pmax -= scnoffs;
+ }
+}
+
+/*
+| from StaticPrimitive
+*/
+bool shaveVrayStaticTriVoxelPrim::splittable ()
+{
+ //DebugPrint("PRIM> shaveVrayStaticTriVoxelPrim::splitable\n");
+
+ return true;
+}
+
+/*
+| from StaticPrimitive
+*/
+void shaveVrayStaticTriVoxelPrim::split (int dim, VR::real middle, VR::StaticBox &bLeft, VR::StaticBox &bRight)
+{
+ //DebugPrint("PRIM> shaveVrayStaticTriVoxelPrim::split [%i %f]\n",dim,middle);
+
+ VR::StaticBox bbox;
+ getBBox(bbox);
+ bbox.split(dim, middle, bLeft, bRight);
+}
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticTriVoxelPrim::expandable()
+{
+ return true;
+}
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticTriVoxelPrim::expand (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex)
+{
+
+ const HairType& hair = voxel()->GetHair();
+ int numFaces = hair.GetNumFaces();
+ int numVerts = hair.GetNumVerts();
+
+ if(numFaces == 0)
+ return 0;
+
+ if(firstid() == -1)
+ _firstid() = raycaster->getNewRenderIDArray(numFaces);
+
+ _normals().resize(numVerts);
+ for(int i = 0; i < numVerts; i++)
+ {
+ _normal(i) = VR::Vector(0.0f,0.0f,0.0f);
+ }
+
+ VR::Vector scnoffs = VR::toVector(sceneOffset());
+ _tris() = new VR::StaticTriangle[numFaces];
+ for(int i = 0; i < numFaces; i++)
+ {
+ int fs;
+ int fe;
+ int k = 0;
+ //int k = 2;
+ hair.GetFace(i,fs,fe);
+ int df = fe - fs; //we expect triangular mesh
+ if(df != 3)
+ {
+ LOGMSGI("PRIM", "triangular face is expected, vertex count:",df);
+ continue;
+ }
+ for(int j = fs; j < fe; j++)
+ {
+ int vert_idx = hair.GetFaceVert(j);
+ hair.GetVert(vert_idx,_tri(i).p[k].x,_tri(i).p[k].y,_tri(i).p[k].z);
+ _tri(i).p[k] -= scnoffs;
+ k++;
+ //k--;
+ }
+ raycaster->insertPrimitive(threadIndex, &_tri(i), static_cast<GeometryGenerator*>(this), i + firstid());
+
+ // pre-compute normals
+ int i0 = hair.GetFaceVert(fs);
+ int i1 = hair.GetFaceVert(fs+1);
+ int i2 = hair.GetFaceVert(fs+2);
+ VR::Vector v0;
+ VR::Vector v1;
+ VR::Vector v2;
+ hair.GetVert(i0,v0.x,v0.y,v0.z);
+ hair.GetVert(i1,v1.x,v1.y,v1.z);
+ hair.GetVert(i2,v2.x,v2.y,v2.z);
+
+ VR::Vector e0 = v1-v0;
+ VR::Vector e1 = v2-v0;
+
+ VR::Vector fn = -normalize(e0^e1);
+
+ _normal(i0) += fn;
+ _normal(i1) += fn;
+ _normal(i2) += fn;
+
+ }
+
+ for(int i = 0; i < numVerts; i++)
+ {
+ _normal(i) = normalize(normal(i));
+ }
+
+#ifdef _DEBUG
+#ifdef WIN32
+ assert(_CrtCheckMemory());
+#endif
+#endif
+ return numFaces*sizeof(VR::StaticTriangle);
+}
+
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticTriVoxelPrim::collapse (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex)
+{
+ // printf("PRIM> shaveVrayStaticVoxelPrim::collapse\n");fflush(stdout);
+
+ const HairType& hair = voxel()->GetHair();
+ int numFaces = hair.GetNumFaces();
+
+ if(numFaces == 0)
+ return 0;
+
+ if(tris())
+ {
+ for (int i=0; i < numFaces; i++)
+ raycaster->removePrimitive(threadIndex, &_tri(i));
+
+ delete[] tris();
+ _tris() = NULL;
+ }
+
+ return numFaces*sizeof(VR::StaticTriangle);
+}
+
+
+/*
+| from GeometryGenerator
+*/
+//VR::Vector shaveVrayStaticTriVoxelPrim::getGNormal(VR::RSRay &rsray)
+//{
+// return rsray.is.primitive->getGNormal(rsray);
+//}
+/*
+| from GeometryGenerator
+*/
+//VR::Vector shaveVrayStaticTriVoxelPrim::getNormal(VR::RSRay &rsray)
+//{
+// return rsray.is.primitive->getNormal(rsray);
+//}
+/*
+| from GeometryGenerator
+*/
+void shaveVrayStaticTriVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd)
+{
+ VR::IntersectionData &isData=*((VR::IntersectionData*) isd);
+ VR::RSIntersection &is=rsray.is;
+
+ assert(PRIM_TYPE_STATIC_TRIANGLE == is.primitive->type());
+
+ shaveVrayStaticTriVoxelPrim* owner =(shaveVrayStaticTriVoxelPrim*) (is.primitive->owner);
+ assert(owner == this);
+
+ VR::StaticTriangle* T = (VR::StaticTriangle*)is.primitive;
+
+
+ const HairType& hair = voxel()->GetHair();
+
+ isData.primitive=is.primitive;
+ isData.skipTag =is.skipTag;
+ isData.faceIndex= T->ownerIndex - firstid();
+
+#ifdef OWN_SHADEABLE_FOR_TRI
+ isData.sb = shade();
+#else
+ isData.sb = shdata();
+#endif
+ isData.sd = shdata();
+ isData.si = NULL; //shinst();
+ isData.volume=NULL;
+
+ isData.bary=VR::toShadeVec(is.bary);
+ isData.wpointCoeff=is.t;
+
+ isData.faceBase=VR::toShadeVec(T->p[0]);
+ isData.faceEdge0=VR::toShadeVec(T->p[1]);
+ isData.faceEdge1=VR::toShadeVec(T->p[2]);
+ isData.faceEdge0-=isData.faceBase;
+ isData.faceEdge1-=isData.faceBase;
+
+ isData.gnormal= -normalize(isData.faceEdge0^isData.faceEdge1); //VR::Vector();
+#if 0
+ isData.normal = isData.gnormal;//T->getNormal(rsray);
+#else
+ int fs;
+ int fe;
+ hair.GetFace(isData.faceIndex,fs,fe);
+
+ int v0 = hair.GetFaceVert(fs);
+ int v1 = hair.GetFaceVert(fs+1);
+ int v2 = hair.GetFaceVert(fs+2);
+
+ VR::ShadeVec n0 = VR::toShadeVec(normal(v0));
+ VR::ShadeVec n1 = VR::toShadeVec(normal(v1));
+ VR::ShadeVec n2 = VR::toShadeVec(normal(v2));
+ VR::ShadeVec N = is.bary.x*n0 + is.bary.y*n1 + is.bary.z*n2;
+ isData.normal = normalize(N);
+
+#endif
+ isData.wpoint=VR::toShadeVec(rsray.p) + VR::toShadeVec(rsray.dir)*is.t;
+
+ // We don't have any meaningful data here
+ isData.surfaceProps = NULL; // sfprops();
+}
+
+#if defined(VRAY30)
+
+void shaveVrayStaticTriVoxelPrim::setIntersectionData(const VR::RayBunchParams& params,
+ VR::PrimitiveIntersections& result,
+ const RAY_IDX* idxs,
+ size_t count)
+{
+ for(size_t ii=0; ii<count; ++ii) {
+ const RAY_IDX idx=idxs[ii];
+ // ray direction
+ VR::Vector dir(params.dirs(0)[idx], params.dirs(1)[idx], params.dirs(2)[idx]);
+
+ VR::StaticTriangle* T = (VR::StaticTriangle*)(result.primitives()[idx]);
+
+ shaveVrayStaticTriVoxelPrim* owner = static_cast<shaveVrayStaticTriVoxelPrim*>(result.primitives()[idx]->owner);
+ assert(owner == this);
+
+ const HairType& hair = voxel()->GetHair();
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ int fs = T->ownerIndex - firstid();
+ result.faceIndices()[idx] = fs;
+
+ result.skipTags()[idx] = params.parentSkipTags()[idx];
+
+ //VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment
+ double dist = result.rayDistances()[ idx ];
+ double isectPtX = params.origins(0)[ idx ] + params.dirs(0)[ idx ] * dist;
+ double isectPtY = params.origins(1)[ idx ] + params.dirs(1)[ idx ] * dist;
+ double isectPtZ = params.origins(2)[ idx ] + params.dirs(2)[ idx ] * dist;
+
+ result.isectPoints(0)[idx] = isectPtX;
+ result.isectPoints(1)[idx] = isectPtY;
+ result.isectPoints(2)[idx] = isectPtZ;
+
+ VR::Vector gn = T->getGNormal(params, result, idx);
+ if (VR::dotf(dir, gn) < 0) gn = -gn;
+ result.geomNormals(0)[idx] = gn[0];
+ result.geomNormals(1)[idx] = gn[1];
+ result.geomNormals(2)[idx] = gn[2];
+
+ int v0 = hair.GetFaceVert(fs);
+ int v1 = hair.GetFaceVert(fs+1);
+ int v2 = hair.GetFaceVert(fs+2);
+
+ VR::Vector sn = normalize0(
+ result.baryCoords(0)[idx] * normal(v0) +
+ result.baryCoords(1)[idx] * normal(v1) +
+ result.baryCoords(2)[idx] * normal(v2));
+ if (VR::dotf(dir, sn) < 0) sn = -sn;
+ result.smoothNormals(0)[idx] = sn[0];
+ result.smoothNormals(1)[idx] = sn[1];
+ result.smoothNormals(2)[idx] = sn[2];
+
+ for(int d=0; d<3; d++)
+ result.facesBase(d)[idx]=T->p[0][d];
+ for(int d=0; d<3; d++)
+ result.facesEdge0(d)[idx]=T->p[1][d]-T->p[0][d];
+ for(int d=0; d<3; d++)
+ result.facesEdge1(d)[idx]=T->p[2][d]-T->p[0][d];
+ }
+}
+
+#endif // VRAY30
diff --git a/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.h b/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.h
new file mode 100644
index 0000000..ebcac5e
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayStaticTriVoxelPrim.h
@@ -0,0 +1,100 @@
+#ifndef _HAIR_VR_STATIC_tri_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_STATIC_tri_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayStaticTriVoxelPrim.h
+
+ DESCRIPTION: Staic (non motion blurred) hair instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayTriVoxelPrim.h"
+#include "hairprimitives.h"
+
+#include <vector>
+
+class shaveVrayStaticTriVoxelPrim : public shaveVrayTriVoxelPrim,
+ public VR::StaticPrimitive {
+public:
+ shaveVrayStaticTriVoxelPrim(IHairVoxel* voxel, VR::VRayCore *vray, shaveVrayInstanceI* inst);
+ virtual ~shaveVrayStaticTriVoxelPrim();
+
+ /*
+ | from StaicPrimitive
+ */
+ // Return the bounding box of this primitive.
+ void getBBox (VR::StaticBox &bbox);
+
+ //Return true if the primitive is splittable.
+ bool splittable ();
+
+ //Return the bounding boxes of the primitive with respect to a given plane.
+ void split (int dim, VR::real middle, VR::StaticBox &bLeft, VR::StaticBox &bRight);
+
+ //Return true here
+ int expandable();
+
+ //Expand the primitive into other sub-primitives.
+ int expand (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex);
+
+ //Collapse the primitive.
+ int collapse (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex);
+
+ /*
+ | from GeometryGenerator
+ */
+ void setIntersectionData(VR::RSRay &rsray, void *isData);
+
+#if defined VRAY30
+ void setIntersectionData(const VR::RayBunchParams& params,
+ VR::PrimitiveIntersections& result,
+ const RAY_IDX* idxs,
+ size_t count);
+#endif
+
+#ifdef OWN_SHADEABLE_FOR_TRI
+ VR::Shadeable* getShadeable() { return shade(); }
+#else
+ VR::Shadeable* getShadeable() { return shdata(); }
+#endif
+ VR::VRayShadeInstance* getExtShadeData() { return NULL; }
+ VR::VRayShadeData* getExtTexMapping() { return shdata(); }
+ VR::VRayVolume* getVolumeShader() { return NULL; }
+ VR::VRaySurfaceProperties* getExtSurfaceProperties() { return NULL; }
+
+protected:
+
+ //const member access
+ inline const std::vector<VR::Vector>& normals() const {return m_normals;}
+ inline const VR::Vector& normal(int i) const {return m_normals[i];}
+ inline const VR::StaticTriangle& tri(int i) const {return m_tris[i];}
+ inline VR::StaticTriangle* tris() const {return m_tris;}
+ inline int firstid() const {return m_firstid;}
+
+ //member access
+ inline std::vector<VR::Vector>& _normals() {return m_normals;}
+ inline VR::Vector& _normal(int i) {return m_normals[i];}
+ inline VR::StaticTriangle& _tri(int i) {return m_tris[i];}
+ inline VR::StaticTriangle*& _tris() {return m_tris;}
+
+ inline int& _firstid() {return m_firstid;}
+
+private:
+
+ int m_firstid;
+ VR::StaticTriangle* m_tris;
+ std::vector<VR::Vector> m_normals;
+};
+
+
+#endif //end of_HAIR_VR_STATIC_tri_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp
new file mode 100644
index 0000000..b116873
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.cpp
@@ -0,0 +1,790 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayStaticVoxelPrim.cpp -- iplementation file
+
+ DESCRIPTION: Static (non motion blurred) hair primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayStaticVoxelPrim.h"
+#include "shaveVrayInstance.h"
+//#include "HairVrPrimsSharedFunctions.h"
+#include "misc_ray.h"
+
+#if defined(VRAY30) || defined(VRAY40)
+using namespace VUtils;
+#endif
+
+shaveVrayStaticVoxelPrim::shaveVrayStaticVoxelPrim(IHairVoxel* voxel,VR::VRayCore *vray, shaveVrayInstance *inst)
+ :shaveVrayVoxelPrim(voxel,vray,inst)
+#if defined(VRAY30) || defined(VRAY40)
+ ,staticHairTree(NULL)
+#endif
+
+{
+ _firstid() = -1;
+ _pts() = NULL;
+ _uns() = NULL;
+ _vns() = NULL;
+ _strands() = NULL;
+#if defined(VRAY30) || defined(VRAY40)
+ minLeaf=0.0f;
+ leafCoeff=1.0f;
+ maxDepth=80;
+
+ const VRaySequenceData &sdata=vray->getSequenceData();
+ const VRayFrameData &fdata=vray->getFrameData();
+
+ threadman=sdata.threadManager;
+ prog=sdata.progress;
+#if VRAY_DLL_VERSION < 0x36000
+ tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth);
+#else
+ tessParams.setFDataParams(fdata.camToWorld.offs, fdata.fov, fdata.imgWidth, fdata.worldToCam, fdata.projType, fdata.zoomFractor, fdata.devAspect);
+#endif
+ tessParams.setSubdivThresh(inst->plugin->edgeLen);
+#else
+ _pool_Vector().init(sizeof(VR::Vector)*3*numknots(), 1000);
+#endif
+}
+
+shaveVrayStaticVoxelPrim::~shaveVrayStaticVoxelPrim()
+{
+ //these should be released in ::collapse()
+ //but we add this code here in any case
+ if(pts())
+ delete [] pts();
+
+ if(uns())
+ delete [] uns();
+
+ if(vns())
+ delete [] vns();
+#if defined(VRAY30) || defined(VRAY40)
+ if(staticHairTree)
+ delete staticHairTree;
+#endif
+}
+
+/*
+| from StaticPrimitive
+*/
+void shaveVrayStaticVoxelPrim::getBBox (VR::StaticBox &bbox)
+{
+ //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::getBBox ");
+
+ if(voxel())
+ {
+ VERT pmin;
+ VERT pmax;
+ voxel()->GetBbox(pmin,pmax);
+
+ bbox.pmin.x = pmin.x;
+ bbox.pmin.y = pmin.y;
+ bbox.pmin.z = pmin.z;
+
+ bbox.pmax.x = pmax.x;
+ bbox.pmax.y = pmax.y;
+ bbox.pmax.z = pmax.z;
+
+ /*DebugPrint("[%f %f %f][%f %f %f]\n",
+ bbox.pmin.x, bbox.pmin.y, bbox.pmin.z,
+ bbox.pmax.x, bbox.pmax.y, bbox.pmax.z);*/
+
+ VR::Vector scnoffs = VR::toVector(sceneOffset());
+ bbox.pmin -= scnoffs;
+ bbox.pmax -= scnoffs;
+ }
+}
+
+/*
+| from StaticPrimitive
+*/
+bool shaveVrayStaticVoxelPrim::splittable ()
+{
+ //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::splitable\n");
+
+ return true;
+}
+
+/*
+| from StaticPrimitive
+*/
+void shaveVrayStaticVoxelPrim::split (int dim, VR::real middle, VR::StaticBox &bLeft, VR::StaticBox &bRight)
+{
+ //DebugPrint("PRIM> shaveVrayStaticVoxelPrim::split [%i %f]\n",dim,middle);
+
+ VR::StaticBox bbox;
+ getBBox(bbox);
+ bbox.split(dim, middle, bLeft, bRight);
+}
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticVoxelPrim::expandable()
+{
+ return true;
+}
+
+
+/*
+| from StaticHairGenerator
+*/
+int shaveVrayStaticVoxelPrim::getNumSides() const
+{
+ return 4;
+}
+
+/*
+| from StaticHairGenerator
+*/
+int shaveVrayStaticVoxelPrim::getNumKnots()
+{
+ return numknots();
+}
+/*
+| from StaticHairGenerator
+*/
+void shaveVrayStaticVoxelPrim::getSidesUV(float *&uc, float *&vc)
+{
+ uc = _puc();
+ vc = _pvc();
+}
+/*
+| from StaticHairGenerator
+*/
+void shaveVrayStaticVoxelPrim::getSidesUV(const float *&uc, const float *&vc) const
+{
+ uc = puc();
+ vc = pvc();
+ //int size = eNumSides*sizeof(float);
+ //memcpy((void*)uc,puc(),size);
+ //memcpy((void*)vc,pvc(),size);
+}
+/*
+| from StaticHairGenerator
+*/
+int shaveVrayStaticVoxelPrim::getFlatNormal() const
+{
+ return true;
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getRadius()
+{
+ return 1.0f; //not sure
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getLength()
+{
+ return 100.f; //not sure
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getTaper()
+{
+ return 0.0f; //not sure
+}
+/*
+| from StaticHairGenerator
+*/
+VR::Vector shaveVrayStaticVoxelPrim::getGravity()
+{
+ return VR::Vector(0.0f, 0.0f, 0.0f); //not sure
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getLengthRand()
+{
+ return 0.0f;
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getRadiusRand()
+{
+ return 0.0f;
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getGravityRand()
+{
+ return 0.0f;
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getDirRand()
+{
+ return 0.0f;
+}
+/*
+| from StaticHairGenerator
+*/
+float shaveVrayStaticVoxelPrim::getBend()
+{
+ return 0.0f;
+}
+int shaveVrayStaticVoxelPrim::generateStrand(int faceIndex, int strandIndex,
+ const VR::Vector *pv, const VR::Vector *nv,
+ VR::Vector *pts, VR::Vector *un, VR::Vector *vn)
+{
+ assert(false);
+ //maybe we do not need to change array elementws as far as we passed initalized strands
+ return true;
+}
+/*
+| from StaticHairGenerator
+*/
+VR::Vector shaveVrayStaticVoxelPrim::getStrandBaryCoords(int faceIndex, int strandIndex) const
+{
+ return VR::Vector(1.0f, 0.0f, 0.f);
+}
+/*
+| from StaticHairGenerator
+*/
+VR::Vector* shaveVrayStaticVoxelPrim::newVectors(int threadIndex)
+{
+#if defined(VRAY30) || defined(VRAY40)
+ return NULL;
+#else
+ return (VR::Vector*) _pool_Vector().newElement();
+#endif
+}
+/*
+| from StaticHairGenerator
+*/
+void shaveVrayStaticVoxelPrim::deleteVectors(VR::Vector *x, int threadIndex)
+{
+ _pool_Vector().releaseElement(x);
+}
+
+/*
+| from GeometryGenerator
+*/
+#if defined(VRAY30)
+VR::Vector shaveVrayStaticVoxelPrim::getGNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getGNormal(rsray);
+}
+VR::Vector shaveVrayStaticVoxelPrim::getNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getNormal(rsray);
+}
+#elif defined(VRAY40)
+VR::ShadeVec shaveVrayStaticVoxelPrim::getGNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getGNormal(rsray);
+}
+VR::ShadeVec shaveVrayStaticVoxelPrim::getNormal(VR::RSRay &rsray)
+{
+ return rsray.is.primitive->getNormal(rsray);
+}
+#endif
+
+#if defined(VRAY30) || defined(VRAY40)
+/*
+ * ###########################################
+ * Implementation for V-Ray 3.0+
+ * ###########################################
+ */
+int shaveVrayStaticVoxelPrim::initHairData() {
+ const HairType &hair=voxel()->GetHair();
+ int numHairs=hair.GetNumStrands();
+
+ //assume all hairs have the same number of segments
+ _numknots()=hair.face_end[0]-hair.face_start[0];
+
+ // hair data will hold data from voxel
+ hairData.numVertices=VR::IntRefList(numHairs);
+ hairData.vertices=VR::VectorRefList(numHairs*_numknots());
+ hairData.widths=VR::FloatRefList(numHairs*_numknots());
+ hairData.colors=VR::ColorRefList(numHairs*_numknots());
+
+ VR::Vector scnoffs=VR::toVector(sceneOffset());
+ // fill in our hair data
+ for(int i=0; i<numHairs; ++i) {
+ int pts_offset=i*numknots();
+
+ float root_radius=hair.radiusroot[i];
+ float delta_radius=hair.radiustip[i]-root_radius;
+
+ for(int j=0; j<numknots(); ++j) {
+ int vert_idx=hair.face_start[i] + j;
+ int pt_idx=pts_offset+j;
+
+ VR::Vector pt;
+ hair.GetVert(vert_idx, pt.x, pt.y, pt.z);
+ pt-=scnoffs;
+ hairData.vertices[pt_idx]=pt;
+
+ float t=float(j)/float(numknots()-1);
+ float w=VR::Max(0.0001f, root_radius+t*delta_radius);
+ hairData.widths[pt_idx]=w;
+
+ VR::Color knot_color;
+ hair.GetVertColor(i, j, knot_color.r, knot_color.g, knot_color.b);
+ hairData.colors[pt_idx]=knot_color;
+ }
+ hairData.numVertices[i]=_numknots();
+ }
+
+ hairData.initVertexOffsets();
+
+ tmHairData.hairData=&hairData;
+ tmHairData.worldSpaceVertices=hairData.vertices;
+ tmHairData.initDirs();
+
+ if (hinst()->plugin->dynHairTessel) {
+ tesselateHairData(tmHairData, &tessHairData, NULL, NULL, tessParams);
+ }
+
+ return numHairs;
+}
+
+#if defined(VRAY30)
+void shaveVrayStaticVoxelPrim::storeInGlobalTree(VR::RayServerInterface2 *rayserver)
+#elif defined(VRAY40)
+void shaveVrayStaticVoxelPrim::storeInGlobalTree(VR::RayServerInterface *rayserver)
+#endif
+{
+ if (!staticHairTree) {
+ int num_hairs=initHairData();
+ if(firstid()==-1)
+ _firstid()=rayserver->getNewRenderIDArray(num_hairs+1);
+ staticHairTree=new StaticHairTreePrimitive(firstid(), &tmHairData, NULL, 0);
+ }
+ rayserver->storeStaticHairData(staticHairTree, this, firstid(), tmHairData);
+}
+
+int shaveVrayStaticVoxelPrim::expand(VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) {
+
+ int num_hairs=initHairData();
+
+ if(firstid()==-1)
+ _firstid()=raycaster->getNewRenderIDArray(num_hairs+1);
+
+#if VRAY_DLL_VERSION < 0x31000
+ staticHairTree=new VR::StaticHairTreePrimitive(firstid()+1, &tmHairData, NULL, true);
+#else
+#if VRAY_DLL_VERSION >= 0x40000
+ RayServerInterface* rayserver = vrayCore->getSequenceData().rayserver;
+#else
+ RayServerInterface2* rayserver = vrayCore->getSequenceData().rayserver;
+#endif
+ VoxelTree * tree = rayserver->newStaticVoxelTree(&tmHairData, voxelTreeType_hairTree);
+ staticHairTree=new StaticHairTreePrimitive(firstid()+1, &tmHairData, NULL, tree);
+#endif
+
+#if VRAY_DLL_VERSION < 0x36000
+ staticHairTree->visibleToCamera=_hinst()->primary_visibility; // should we intersect this hair tree wil cam rays?
+#else
+ staticHairTree->visibleToCamera = _hinst()->getPrimaryVisibility();
+#endif
+ staticHairTree->build(prog, threadman, maxDepth, minLeaf, leafCoeff);
+
+ raycaster->insertPrimitive(threadIndex, staticHairTree, this, firstid());
+
+ int totalVertices=numknots()*num_hairs;
+ uint64 memUsage=staticHairTree->getMemUsage();
+ return memUsage+3*sizeof(VR::Vector)*totalVertices;
+}
+
+int shaveVrayStaticVoxelPrim::collapse(VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex) {
+ raycaster->removePrimitive(threadIndex, staticHairTree);
+ uint64 memUsage=staticHairTree->getMemUsage();
+ delete staticHairTree;
+ staticHairTree=NULL;
+ memUsage+=3*sizeof(Vector)*tmHairData.hairData->vertices.size();
+
+ tmHairData.freeMem();
+ hairData.freeMem();
+ tessHairData.freeMem();
+
+ return memUsage;
+}
+
+void shaveVrayStaticVoxelPrim::getStaticIntersectionData(int strandIdx, int segmentIdx, const VR::Vector* &p, const VR::Vector* &dirs) {
+ int startIdx = tmHairData.hairData->vertexOffsets[strandIdx] + segmentIdx;
+ p = &tmHairData.worldSpaceVertices[startIdx];
+ dirs = &tmHairData.dirs[startIdx];
+}
+
+void shaveVrayStaticVoxelPrim::setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const ShadeVec &gNormal, const ShadeVec &normal)
+{
+ IntersectionData &isData=*((IntersectionData*) isd);
+ RSIntersection &is=rsray.is;
+
+ isData.primitive=rsray.is.primitive;
+ isData.skipTag=is.skipTag;
+
+ isData.sb=getShadeable();
+ isData.sd=getExtTexMapping();
+ isData.si=getExtShadeData();
+
+ isData.surfaceProps=NULL;
+ isData.volume=NULL;
+
+ isData.wpointCoeff=is.t;
+#if defined(VRAY30)
+ isData.wpoint=rsray.p+TracePoint(rsray.dir)*is.t;
+#elif defined(VRAY40)
+ isData.wpoint=rsray.p+rsray.dir*is.t;
+#endif
+
+ isData.gnormal=gNormal;
+ isData.normal=normal;
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ isData.extra_int[1]=strandIdx; // the hair strand index
+ isData.faceIndex=segmentIdx; // the segment index within a hair strand
+
+ isData.bary = ShadeVec(wParam, 0.0f, 0.0f); // the length along the segment
+
+ isData.faceBase = ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.faceEdge0 = ShadeVec(0.0f, 0.0f, 0.0f);
+ isData.faceEdge1 = ShadeVec(0.0f, 0.0f, 0.0f);
+}
+
+#if defined(VRAY30)
+void shaveVrayStaticVoxelPrim::setCommonIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result,
+ const RAY_IDX idx, int strandIdx, int segmentIdx, float wParam,
+ const VUtils::Vector &gNormal, const VUtils::Vector &normal)
+{
+ VR::Ireal t = result.rayDistances()[ idx ];
+ for(int d=0; d<3; d++) result.isectPoints(d)[idx] = params.origins(d)[idx] + params.dirs(d)[idx] * t;
+
+ for(int d=0; d<3; d++) result.geomNormals(d)[idx] = gNormal[d];
+
+ for(int d=0; d<3; d++) result.smoothNormals(d)[idx] = normal[d];
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ result.extraInts(1)[idx] = strandIdx; // the hair strand index
+ result.faceIndices()[idx] = segmentIdx; // the segment index within a hair strand
+
+ VR::Vector bary = VR::Vector(wParam, 0.0f, 0.0f); // the length along the segment
+ for(int d=0; d<3; d++) result.baryCoords(d)[idx] = bary[d];
+
+ for(int d=0; d<3; d++) result.facesBase(d)[idx] = 0.0f;
+ for(int d=0; d<3; d++) result.facesEdge0(d)[idx] = 0.0f;
+ for(int d=0; d<3; d++) result.facesEdge1(d)[idx] = 0.0f;
+}
+#endif
+
+void shaveVrayStaticVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd) {
+ VR::StaticHairTreePrimitive *treePrim=static_cast<VR::StaticHairTreePrimitive*>(rsray.is.primitive);
+ int strandIdx=treePrim->getStrandIndex(rsray);
+ int segmentIdx=treePrim->getSegmentIndex(rsray);
+
+ const VR::Vector *p, *dirs;
+ getStaticIntersectionData(strandIdx, segmentIdx, p, dirs);
+
+ setCommonIntersectionData(rsray, isd, strandIdx, segmentIdx,
+ treePrim->getWparam(rsray, p),
+ treePrim->getGNormal(rsray, p),
+ treePrim->getNormal(rsray, p, dirs, getFlatNormal()));
+}
+
+#if defined(VRAY30)
+void shaveVrayStaticVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count)
+{
+ // Iterate over the active rays
+ for( size_t i = 0; i < count; i++ ) {
+ const RAY_IDX idx = idxs[ i ];
+
+ VR::StaticHairTreePrimitive *treePrim=static_cast<VR::StaticHairTreePrimitive*>(result.primitives()[idx]);
+
+ int strandIdx=treePrim->getStrandIndex(params, result, idx);
+ int segmentIdx=treePrim->getSegmentIndex(params, result, idx);
+
+ const VR::Vector *p, *dirs;
+ getStaticIntersectionData(strandIdx, segmentIdx, p, dirs);
+
+ setCommonIntersectionData(params, result, idx, strandIdx, segmentIdx,
+ treePrim->getWparam(params, result, idx, p),
+ treePrim->getGNormal(params, result, idx, p),
+ treePrim->getNormal(params, result, idx, p, dirs, getFlatNormal()));
+ }
+}
+#endif
+
+VR::ShadeVec shaveVrayStaticVoxelPrim::getHairDir(const VR::VRayContext &rc) const {
+ int strandIdx, segmentIdx;
+ shaveVrayGetHairParams(rc, strandIdx, segmentIdx);
+
+ int pos=hairData.vertexOffsets[strandIdx]+segmentIdx;
+ float blend=rc.rayresult.bary[0];
+
+ VR::ShadeVec result(0.0f, 0.0f, 0.0f);
+
+ const VR::VectorRefList &vertices=tmHairData.worldSpaceVertices;
+ if (segmentIdx==0) {
+ VR::ShadeVec v=VR::toShadeVec(vertices[pos]);
+ VR::ShadeVec vnext=VR::toShadeVec(vertices[pos+1]);
+ result=normalize0(vnext-v);
+ } else {
+ VR::ShadeVec vprev=VR::toShadeVec(vertices[pos-1]);
+ VR::ShadeVec v=VR::toShadeVec(vertices[pos]);
+ VR::ShadeVec vnext=VR::toShadeVec(vertices[pos+1]);
+ VR::ShadeVec prev_dir = normalize0(v-vprev);
+ VR::ShadeVec curr_dir = normalize0(vnext-v);
+
+ result=normalize0(prev_dir + (curr_dir - prev_dir)*blend);
+ }
+
+ return result;
+}
+
+#else //VRAY30 not defined below this line
+/*
+ * ###########################################
+ * Implementation for V-Ray <= 2.99
+ * ###########################################
+ */
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticVoxelPrim::expand (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex)
+{
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(numHairs == 0)
+ return 0;
+
+ if(firstid() == -1)
+ _firstid() = raycaster->getNewRenderIDArray(numHairs);
+
+ //assume all hairs have the same number of segments
+ _numknots() = hair.face_end[0] - hair.face_start[0];
+
+ int nalloc = numknots()*numHairs;
+ _pts() = new VR::Vector[nalloc];
+ _uns() = new VR::Vector[nalloc];
+ _vns() = new VR::Vector[nalloc];
+
+ _strands() = new VR::StaticHairStrand[numHairs];
+ for(int i = 0; i < numHairs; i++)
+ {
+ int pts_offset = i*numknots();
+
+ float root_radius = hair.radiusroot[i];
+ float delta_radius = hair.radiustip[i] - root_radius;
+
+ VR::Vector initialNormal;
+ VR::Vector sv0, sv1;
+ hair.GetVert(0, sv0.x, sv0.y, sv0.z);
+ hair.GetVert(1, sv1.x, sv1.y, sv1.z);
+ initialNormal=VR::normalize0(sv1-sv0);
+
+ // Compute the initial tangent vectors - these are later on propagated along the
+ // strand length to avoids issues with flipped tangent vectors.
+ VR::Vector u,v;
+ VR::computeTangentVectors(initialNormal, u, v);
+
+ for(int j = 0; j < numknots(); j++)
+ {
+ int vert_idx = hair.face_start[i] + j;
+ int pt_idx = pts_offset + j;
+
+ hair.GetVert(vert_idx,_pt(pt_idx).x,_pt(pt_idx).y,_pt(pt_idx).z);
+
+ _pt(pt_idx) -= sceneOffset();
+
+ if(j == 0)
+ {
+ float radius = root_radius;
+ if (radius<0.0001f) radius=0.0001f;
+
+ // For the first point, just use the tangent vectors directly
+ _un(pt_idx) = u*radius;
+ _vn(pt_idx) = v*radius;
+ }
+ else
+ {
+ float t = (float)j/(float)(numknots()-1);
+ float radius = root_radius + t*delta_radius;
+ if (radius<0.0001f) radius=0.0001f;
+
+ VR::Vector v0, v1;
+ hair.GetVert(vert_idx, v1.x, v1.y, v1.z);
+ hair.GetVert(vert_idx-1, v0.x, v0.y, v0.z);
+
+ VR::Vector d=v1-v0;
+ float dlenSqr=d.lengthSqr();
+ if (dlenSqr>1e-12f) {
+ VR::Vector nu=u-d*((u*d)/sqrtf(dlenSqr)); // Project the previous u vector on the current cross plane
+ float nuLenSqr=lengthSqr(nu);
+ if (nuLenSqr>1e-12f) {
+ u=nu/sqrtf(nuLenSqr);
+ v=normalize(d^nu);
+ }
+ }
+
+ _un(pt_idx) = u*radius;
+ _vn(pt_idx) = v*radius;
+ }
+ }
+
+ _strand(i).init(static_cast<StaticHairGenerator*>(this),pts(pts_offset), uns(pts_offset), vns(pts_offset));
+
+ raycaster->insertPrimitive(threadIndex, &_strand(i), static_cast<GeometryGenerator*>(this), i + firstid());
+ }
+#ifdef _DEBUG
+#ifdef WIN32
+ assert(_CrtCheckMemory());
+#endif
+#endif
+ return numHairs*sizeof(VR::StaticHairStrand) + numknots()*numHairs*3*sizeof(VR::Vector);
+}
+
+/*
+| from StaticPrimitive
+*/
+int shaveVrayStaticVoxelPrim::collapse (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex)
+{
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(numHairs == 0)
+ return 0;
+
+ if(strands())
+ {
+ for (int i=0; i < numHairs; i++)
+ raycaster->removePrimitive(threadIndex, &_strand(i));
+
+ delete[] strands();
+ _strands() = NULL;
+ }
+ if(pts())
+ {
+ delete [] pts();
+ _pts() = NULL;
+ }
+ if(uns())
+ {
+ delete [] uns();
+ _uns() = NULL;
+ }
+ if(vns())
+ {
+ delete [] vns();
+ _vns() = NULL;
+ }
+ _pool_Vector().freeMem();
+
+ return numHairs*sizeof(VR::StaticHairStrand) + numknots()*numHairs*3*sizeof(VR::Vector);
+}
+
+/*
+| from GeometryGenerator
+*/
+void shaveVrayStaticVoxelPrim::setIntersectionData(VR::RSRay &rsray, void *isd)
+{
+ VR::IntersectionData &isData=*((VR::IntersectionData*) isd);
+ VR::RSIntersection &is=rsray.is;
+
+ //assert(PRIM_TYPE_STATIC_HAIR_SEGMENT_LINE == is.primitive->type());
+
+ VR::StaticHairStrand *s=(VR::StaticHairStrand*) (is.primitive->owner);
+
+// VR::RayParams* rayparams = (VR::RayParams*)rsray.rayparams;
+// assert( rayparams->currentPass == RPASS_GI);
+// assert( rayparams->currentPass == RPASS_LIGHTMAP);
+
+ isData.primitive=is.primitive;
+ isData.skipTag =is.skipTag;
+ isData.faceIndex= s->ownerIndex - firstid();
+
+ if(ownbsdf())
+ isData.sb = shade();
+ else
+ isData.sb = shdata();
+
+ isData.sd = shdata();
+ isData.si = /*NULL;*/ shinst();
+ isData.volume=NULL;
+
+ isData.bary= VR::Vector(0.5f, 0.5f, 0.5f);
+ isData.wpointCoeff=is.t;
+ isData.gnormal=getGNormal(rsray);
+ isData.gnormal.makeNormalized();
+ //if(isData.gnormal.length() < 0.99f)
+ //{
+ // printf("gn %f %f %f\n",isData.gnormal.x, isData.gnormal.y, isData.gnormal.z);
+ // fflush(stdout);
+ //}
+ isData.normal =getNormal(rsray);
+
+ isData.wpoint=rsray.p + VR::TracePoint(rsray.dir)*is.t;
+ isData.extraf=(float) s->getSegmentIndex((VR::StaticHairSegmentLine*) is.primitive);
+ isData.bary[2]=((VR::StaticHairSegmentLine*) is.primitive)->getWparam(rsray);
+
+// Vector *verts=fface->getVerts();
+// isData.faceBase=verts[0];
+// isData.faceEdge0=verts[1]-verts[0];
+// isData.faceEdge1=verts[2]-verts[0];
+
+ // We don't have any meaningful data here
+ isData.surfaceProps = NULL; // sfprops();
+}
+
+void shaveVrayStaticVoxelPrim::setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count)
+{
+ for(size_t ii=0; ii<count; ++ii) {
+ const RAY_IDX idx=idxs[ii];
+
+ VR::StaticHairSegmentLine *segment=static_cast<VR::StaticHairSegmentLine*>(result.primitives()[idx]);
+ VR::StaticHairStrand *strand=static_cast<VR::StaticHairStrand*>(segment->owner);
+
+ float t=result.rayDistances()[idx];
+ for(int d=0; d<3; d++)
+ result.isectPoints(d)[idx]=params.origins(d)[idx]+double(params.dirs(d)[idx])*t;
+
+ VR::Vector gnormal = segment->getGNormal(params, result, idx);
+ for(int d=0; d<3; d++)
+ result.geomNormals(d)[idx]=gnormal[d];
+
+ VR::Vector normal = segment->getNormal(params, result, idx);
+ for(int d=0; d<3; d++)
+ result.smoothNormals(d)[idx]=normal[d];
+
+ // These will be used to get per-vertex attributes like color, transparency, etc.
+ result.faceIndices()[idx]=strand->getSegmentIndex(segment);
+
+// result.extraFloats(6)[idx]=(float)strand->getSegmentIndex(segment); // the segment index within a hair strand
+ result.extraInts(1)[idx]=strand->ownerIndex - firstid(); // emil 10 Nov
+
+ VR::Vector bary(0.5f, 0.5f, segment->getWparam(params, result, idx)); // the length along the segment
+ for(int d=0; d<3; d++)
+ result.baryCoords(d)[idx]=bary[d];
+
+ for(int d=0; d<3; d++)
+ result.facesBase(d)[idx]=0.0f;
+ for(int d=0; d<3; d++)
+ result.facesEdge0(d)[idx]=0.0f;
+ for(int d=0; d<3; d++)
+ result.facesEdge1(d)[idx]=0.0f;
+ }
+}
+
+#endif //VRAY30
diff --git a/vrayPlug/plugin/shaveVrayStaticVoxelPrim.h b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.h
new file mode 100644
index 0000000..82c221e
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayStaticVoxelPrim.h
@@ -0,0 +1,203 @@
+#ifndef _HAIR_VR_STATIC_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_STATIC_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayStaticVoxelPrim.h
+
+ DESCRIPTION: Staic (non motion blurred) hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 20-08-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 31-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayVoxelPrim.h"
+#include "hairprimitives.h"
+
+
+class shaveVrayStaticVoxelPrim : public shaveVrayVoxelPrim,
+ public VR::StaticHairGenerator {
+public:
+ shaveVrayStaticVoxelPrim(IHairVoxel* voxel, VR::VRayCore *vray, shaveVrayInstance* inst);
+ virtual ~shaveVrayStaticVoxelPrim();
+
+ /*
+ | from StaicPrimitive
+ */
+ // Return the bounding box of this primitive.
+ void getBBox (VR::StaticBox &bbox);
+
+ //Return true if the primitive is splittable.
+ bool splittable ();
+
+ //Return the bounding boxes of the primitive with respect to a given plane.
+ void split (int dim, VR::real middle, VR::StaticBox &bLeft, VR::StaticBox &bRight);
+
+ //Return true here
+ int expandable();
+
+ //Expand the primitive into other sub-primitives.
+ int expand (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex);
+
+ //Collapse the primitive.
+ int collapse (VR::DynamicRaycaster< VR::StaticBox > *raycaster, int threadIndex);
+
+ /*
+ | from StaicHairGenerator
+ */
+ // always returns 4
+ int getNumSides(void) const;
+
+ // number of segments in the strand
+ int getNumKnots(void);
+
+ // returns two arrays, of getNumSides() length each,
+ // with the cosine and sine along the circle at regular intervals
+ void getSidesUV(float *&uc, float *&vc);
+ // vlad|8Apr2010 - uc,vc are const now
+ void getSidesUV(const float *&uc, const float *&vc) const;
+
+ //return true to use a simplified normal calculation inside the
+ //StaticHairSegmentLine::getNormal() and getGNormal(), and false to use a more correct model
+ int getFlatNormal(void) const;
+
+ //not sure about these
+ float getRadius();
+ float getLength();
+ float getTaper();
+
+ //hair engine hanles gravity and other forces
+ VR::Vector getGravity();
+
+ //we return 0.0f for all of these
+ float getLengthRand();
+ float getRadiusRand();
+ float getGravityRand();
+ float getDirRand();
+ float getBend();
+
+ int generateStrand(int faceIndex, int strandIndex,
+ const VR::Vector *pv, const VR::Vector *nv,
+ VR::Vector *pts, VR::Vector *un, VR::Vector *vn);
+
+ VR::Vector getStrandBaryCoords(int faceIndex, int strandIndex) const;
+
+ VR::Vector* newVectors(int threadIndex);
+ void deleteVectors(VR::Vector *x, int threadIndex);
+
+ /*
+ | from GeometryGenerator
+ */
+#if defined(VRAY30)
+ VR::Vector getGNormal(VR::RSRay &rsray);
+ VR::Vector getNormal(VR::RSRay &rsray);
+#elif defined(VRAY40)
+ VR::ShadeVec getGNormal(VR::RSRay &rsray);
+ VR::ShadeVec getNormal(VR::RSRay &rsray);
+#endif
+ void setIntersectionData(VR::RSRay &rsray, void *isData);
+#if defined(VRAY30)
+ void setIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result, const RAY_IDX* idxs, size_t count);
+#endif
+
+ VR::Shadeable* getShadeable() { return ownbsdf() ? shade() : shdata(); }
+ VR::VRayShadeInstance* getExtShadeData() { return shinst(); }
+ VR::VRayShadeData* getExtTexMapping() { return shdata(); }
+ VR::VRayVolume* getVolumeShader() { return NULL; }
+ VR::VRaySurfaceProperties* getExtSurfaceProperties() { return NULL; }
+
+#if defined(VRAY30)
+ void storeInGlobalTree(VR::RayServerInterface2 *rayserver);
+#elif defined(VRAY40)
+ void storeInGlobalTree(VR::RayServerInterface *rayserver);
+#endif
+
+#if defined(VRAY30) || defined(VRAY40)
+ // no need to implement, that is used by our automatic hair generation primitives
+ int generateStrand(int faceIndex, int strandIndex, int threadIndex, const VR::Vector *pv,
+ const VR::Vector *nv, VR::Vector *pts, VR::Vector *un, VR::Vector *vn)
+ {
+ return 0;
+ }
+
+ VR::ShadeVec getHairDir(const VR::VRayContext &rc) const;
+#endif
+ //VR::Vector getGNormal(VR::RSRayRef& rsrayref); //3ds Max specific
+ //VR::Vector getNormal(VR::RSRayRef& rsrayref); //3ds Max specific
+ //void setIntersectionData(VR::RSRayRef& rsrayref, void *isData); //3ds Max specific
+
+protected:
+#if defined(VRAY30)
+ void setCommonIntersectionData(const VR::RayBunchParams& params, VR::PrimitiveIntersections& result,
+ const RAY_IDX idx, int strandIdx, int segmentIdx, float wParam,
+ const VUtils::Vector &gNormal, const VUtils::Vector &normal) ;
+#endif
+#if defined(VRAY30) || defined(VRAY40)
+ void getStaticIntersectionData(int strandIdx, int segmentIdx, const VR::Vector* &p, const VR::Vector* &dirs);
+ void setCommonIntersectionData(VR::RSRay &rsray, void *isd, int strandIdx, int segmentIdx,
+ float wParam, const VR::ShadeVec &gNormal, const VR::ShadeVec &normal) ;
+
+ // Returns the number of hair strands
+ int initHairData();
+#endif
+ //const member access
+ inline const VR::StaticHairStrand& strand(int i) const {return m_strands[i];}
+ inline VR::StaticHairStrand* strands() const {return m_strands;}
+ inline const VR::Vector& pt(int i) const {return m_pts[i];}
+ inline const VR::Vector& un(int i) const {return m_uns[i];}
+ inline const VR::Vector& vn(int i) const {return m_vns[i];}
+ inline VR::Vector* pts(int offset) const {return &m_pts[offset];}
+ inline VR::Vector* uns(int offset) const {return &m_uns[offset];}
+ inline VR::Vector* vns(int offset) const {return &m_vns[offset];}
+ inline VR::Vector* pts() const {return m_pts;}
+ inline VR::Vector* uns() const {return m_uns;}
+ inline VR::Vector* vns() const {return m_vns;}
+ inline int firstid() const {return m_firstid;}
+
+ //member access
+ inline VR::StaticHairStrand& _strand(int i) {return m_strands[i];}
+ inline VR::StaticHairStrand*& _strands() {return m_strands;}
+ inline VR::Vector& _pt(int i) {return m_pts[i];}
+ inline VR::Vector& _un(int i) {return m_uns[i];}
+ inline VR::Vector& _vn(int i) {return m_vns[i];}
+ inline VR::Vector*& _pts() {return m_pts;}
+ inline VR::Vector*& _uns() {return m_uns;}
+ inline VR::Vector*& _vns() {return m_vns;}
+ inline int& _firstid() {return m_firstid;}
+
+private:
+
+
+ int m_firstid;
+ VR::Vector* m_pts;
+ VR::Vector* m_uns;
+ VR::Vector* m_vns;
+ VR::StaticHairStrand* m_strands;
+#if defined(VRAY30) || defined(VRAY40)
+ VR::HairData hairData;
+ VR::HairData tessHairData;
+ VR::TransformedHairData tmHairData;
+
+ VR::StaticHairTreePrimitive *staticHairTree;
+
+ int maxDepth;
+ float minLeaf;
+ float leafCoeff;
+
+ VUtils::TessHairParams tessParams;
+
+ VR::ThreadManager *threadman;
+ VR::ProgressCallback *prog;
+#endif
+};
+
+
+#endif //end of_HAIR_VR_STATIC_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/shaveVrayTriShadeData.cpp b/vrayPlug/plugin/shaveVrayTriShadeData.cpp
new file mode 100644
index 0000000..7c1dbc7
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriShadeData.cpp
@@ -0,0 +1,152 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "shaveVrayTriShadeData.h"
+#include "shaveVrayInstanceI.h"
+#include "shaveVrayTriVoxelPrim.h"
+#include "shaveVrayStaticTriVoxelPrim.h"
+#include "misc_ray.h"
+
+
+shaveVrayTriShadeData::shaveVrayTriShadeData(shaveVrayInstanceI *instance)
+ : BaseShadeData(instance)
+{
+}
+
+void shaveVrayTriShadeData::init(const VR::TraceTransform &itm)
+{
+ this->itm=itm*0.01f;
+}
+
+bool shaveVrayTriShadeData::getUVWTriVerts(const VR::VRayContext &rc, VR::ShadeVec &t0, VR::ShadeVec &t1, VR::ShadeVec &t2)
+{
+ shaveVrayInstanceI* I = static_cast<shaveVrayInstanceI*>(instance);
+ const VR::RayResult& rres = rc.rayresult;
+
+ assert(PRIM_TYPE_STATIC_TRIANGLE == rres.primitive->type() ||
+ PRIM_TYPE_MOVING_TRIANGLE == rres.primitive->type());
+
+ if(PRIM_TYPE_STATIC_TRIANGLE != rres.primitive->type() &&
+ PRIM_TYPE_MOVING_TRIANGLE != rres.primitive->type())
+ return false;
+
+ int fidx = rres.faceIndex;
+ if(I->GetNumFacesPerInst() == 0)
+ return false;
+
+ int tidx = fidx % I->GetNumFacesPerInst();
+ int i0 = tidx*3;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+ t0 = toShadeVec(I->GetUV(i0));
+ t1 = toShadeVec(I->GetUV(i1));
+ t2 = toShadeVec(I->GetUV(i2));
+ return true;
+}
+
+#if defined(VRAY30)
+VR::Transform shaveVrayTriShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel)
+{
+ (void) channel; //unused
+ VR::Transform result(1);
+ VR::Vector t0, t1, t2;
+ if (!getUVWTriVerts(rc, t0, t1, t2)) {
+ return result;
+ }
+ const VR::RayResult& rres = rc.rayresult;
+ const VR::Vector& bary = rres.bary;
+ result.offs = bary.x*t0 + bary.y*t1 + bary.z*t2;
+ VR::Vector dt0 = t1 - t0;
+ VR::Vector dt1 = t2 - t0;
+
+ if(!computeUVWMatrix(rres.faceEdge0, rres.faceEdge1, dt0, dt1, result.m))
+ result.m = VR::Matrix(1);
+
+ return result;
+}
+
+VR::Vector shaveVrayTriShadeData::getLocalUVWCoordinates(const VR::VRayContext &rc, int channel)
+{
+ (void) channel; //unused
+ VR::Vector t0, t1, t2;
+ if (!getUVWTriVerts(rc, t0, t1, t2)) {
+ return VR::Vector();
+ }
+ const VR::RayResult& rres = rc.rayresult;
+ const VR::Vector& bary = rres.bary;
+ VR::Vector t = bary.x*t0 + bary.y*t1 + bary.z*t2;
+ return t;
+}
+#elif defined(VRAY40)
+void shaveVrayTriShadeData::getLocalUVWTransform(const VR::VRayContext &rc, int channel, VR::ShadeTransform &result)
+{
+ (void) channel; //unused
+ VR::ShadeVec t0, t1, t2;
+ if (!getUVWTriVerts(rc, t0, t1, t2)) {
+ result.makeIdentity();
+ return;
+ }
+ const VR::RayResult& rres = rc.rayresult;
+ const VR::ShadeVec& bary = rres.bary;
+ result.offs = VR::x(bary)*t0 + VR::y(bary)*t1 + VR::z(bary)*t2;
+ VR::ShadeVec dt0 = t1 - t0;
+ VR::ShadeVec dt1 = t2 - t0;
+
+ if(!VUtils::computeUVWMatrix(rres.faceEdge0, rres.faceEdge1, dt0, dt1, result.m))
+ result.m.makeIdentity();
+}
+
+void shaveVrayTriShadeData::getLocalUVWCoordinates(const VR::VRayContext &rc, int channel, VR::ShadeVec &result)
+{
+ (void) channel; //unused
+ VR::ShadeVec t0, t1, t2;
+ if (!getUVWTriVerts(rc, t0, t1, t2)) {
+ result.makeZero();
+ }
+ const VR::RayResult& rres = rc.rayresult;
+ const VR::ShadeVec& bary = rres.bary;
+ result = VR::x(bary)*t0 + VR::y(bary)*t1 + VR::z(bary)*t2;
+}
+
+int shaveVrayTriShadeData::getLocalUVWTransformByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeTransform &result)
+{
+ (void) rc;
+ (void) channelName;
+ (void) result;
+ return channelNotFound;
+}
+
+int shaveVrayTriShadeData::getUVWCoordinatesByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeVec &result)
+{
+ (void) rc;
+ (void) channelName;
+ (void) result;
+ return channelNotFound;
+}
+
+VR::ShadeVec shaveVrayTriShadeData::getMapChannelVertexVector(int mapChannelIdx, int vertexIdx)
+{
+ (void)mapChannelIdx;
+ (void)vertexIdx;
+ return VR::ShadeVec(0.0f);
+}
+
+VR::ShadeVec shaveVrayTriShadeData::getUVWcoords(const VR::VRayContext &rc, int channel) {
+ return getMappedUVWcoords(rc, *this, channel);
+}
+
+void shaveVrayTriShadeData::getUVWderivs(const VR::VRayContext &rc, int channel, VR::ShadeVec derivs[2]) {
+ getMappedUVWderivs(rc, *this, channel, derivs);
+}
+
+void shaveVrayTriShadeData::getUVWbases(const VR::VRayContext &rc, int channel, VR::ShadeVec bases[3]) {
+ getMappedUVWbases(rc, *this, channel, bases);
+}
+
+VR::ShadeVec shaveVrayTriShadeData::getUVWnormal(const VR::VRayContext &rc, int channel) {
+ return getMappedUVWnormal(rc, *this, channel);
+}
+
+#endif
+
diff --git a/vrayPlug/plugin/shaveVrayTriShadeData.h b/vrayPlug/plugin/shaveVrayTriShadeData.h
new file mode 100644
index 0000000..94366e6
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriShadeData.h
@@ -0,0 +1,72 @@
+#ifndef _HAIR_VRAY_tri_SHADE_DATA_H_
+#define _HAIR_VRAY_tri_SHADE_DATA_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+// V-Ray headers
+#include "vraybase.h"
+#include "vraymayageom.h"
+#include "vrayplugins.h"
+#include "geometryclasses.h"
+#include "hairprimitives.h"
+#include "rayprimitives.h"
+#include "vray3_compat.h"
+
+class shaveVrayInstanceI;
+
+class shaveVrayTriShadeData : public VR::BaseShadeData,
+ public VR::MappedSurface
+{
+ //void getPositionAndBlend(const VR::VRayContext &rc, int &pos, float &blend);
+
+public:
+
+ shaveVrayTriShadeData(shaveVrayInstanceI *instance );
+
+ PluginBase* getPlugin(void) VRAY_OVERRIDE
+ {
+ return NULL;
+ }
+ PluginInterface* newInterface(InterfaceID id) VRAY_OVERRIDE
+ {
+ switch (id) {
+ case EXT_MAPPED_SURFACE: return static_cast<VR::MappedSurface*>(this);
+ }
+ return BaseShadeData::newInterface(id);
+ }
+
+ //VR::Color getColor(const VR::VRayContext &rc);
+ //VR::Color getIncandescence(const VR::VRayContext &rc);
+ //VR::Color getTransparency(const VR::VRayContext &rc);
+ //void getShadeData(const VR::VRayContext &rc, VR::VRayMayaHairShadeData &result);
+
+ // From MappedSurface
+#if defined(VRAY30)
+ VR::Transform getLocalUVWTransform(const VR::VRayContext &rc, int channel) VRAY_OVERRIDE;
+ VR::Vector getLocalUVWCoordinates(const VR::VRayContext &rc, int channel) VRAY_OVERRIDE;
+#elif defined(VRAY40)
+ void getLocalUVWTransform(const VR::VRayContext &rc, int channel, VR::ShadeTransform &result) override;
+ void getLocalUVWCoordinates(const VR::VRayContext &rc, int channel, VR::ShadeVec &result) override;
+ int getLocalUVWTransformByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeTransform &result) override;
+ int getUVWCoordinatesByName(const VR::VRayContext &rc, const VR::StringID &channelName, VR::ShadeVec &result) override;
+ VR::ShadeVec getMapChannelVertexVector(int mapChannelIdx, int vertexIdx) override;
+ VR::ShadeVec getUVWcoords(const VR::VRayContext &vri, int channel) override;
+ void getUVWderivs(const VR::VRayContext &vri, int channel, VR::ShadeVec derivs[2]) override;
+ void getUVWbases(const VR::VRayContext &vri, int channel, VR::ShadeVec bases[3]) override;
+ VR::ShadeVec getUVWnormal(const VR::VRayContext &vri, int channel) override;
+#endif
+
+ void init(const VR::TraceTransform &itm);
+
+private:
+ bool getUVWTriVerts(const VR::VRayContext &rc, VR::ShadeVec &t0, VR::ShadeVec &t1, VR::ShadeVec &t2);
+
+protected:
+
+ VR::TraceTransform itm;
+
+};
+
+#endif
diff --git a/vrayPlug/plugin/shaveVrayTriShadeable.cpp b/vrayPlug/plugin/shaveVrayTriShadeable.cpp
new file mode 100644
index 0000000..417a611
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriShadeable.cpp
@@ -0,0 +1,151 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayTriShadeable.cpp -- implementation file
+
+ DESCRIPTION: Used to shade the instanced surface
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 13-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "shaveVrayTriShadeable.h"
+
+shaveVrayTriShadeable::shaveVrayTriShadeable(shaveVrayTriVoxelPrim *hair)
+{
+ _prim() = hair;
+}
+
+shaveVrayTriShadeable::~shaveVrayTriShadeable()
+{
+ freeBSDFpool();
+}
+/*
+| from Shadeable
+*/
+void shaveVrayTriShadeable::shade(VR::VRayContext &rc)
+{
+ BSDFShadeable::shade(rc);
+
+ if (VUtils::hasNonFiniteLanes(rc.mtlresult.color)) {
+ rc.mtlresult.color.makeZero();
+ }
+//#ifdef USE_WHITE_TRI_BRDF
+// VR::Color c = VR::Color(1.0f, 1.0f, 1.0f);
+// rc.mtlresult.color *= c;
+//#else
+// BSDFShadeable::shade(rc);
+//#endif
+
+ //rc.mtlresult.color.r = 1.0f;
+ //rc.mtlresult.color.g = 0.0f;
+ //rc.mtlresult.color.b = 0.0f;
+
+ //rc.mtlresult.alpha.r = 0.0f;
+ //rc.mtlresult.alpha.g = 0.0f;
+ //rc.mtlresult.alpha.b = 0.0f;
+
+ //rc.mtlresult.transp.r = 0.f;
+ //rc.mtlresult.transp.g = 0.f;
+ //rc.mtlresult.transp.b = 0.f;
+
+ //rc.mtlresult.alphaTransp.r = 0.0f;
+ //rc.mtlresult.alphaTransp.g = 0.0f;
+ //rc.mtlresult.alphaTransp.b = 0.0f;
+}
+/*
+| from Shadeable
+*/
+tchar* shaveVrayTriShadeable::getName(VR::VRayContext &rc)
+{
+ return const_cast<tchar*>("shaveVrayTriShadeable");
+}
+
+VR::BSDFSampler* shaveVrayTriShadeable::newBSDF (const VR::VRayContext &rc, VR::BSDFFlags flags)
+{
+#ifdef USE_WHITE_TRI_BRDF
+ VR::WhiteBRDF *bsdf = _bsdfPool().newBRDF(rc);
+ return bsdf;
+#else
+ #error not implemented
+ //shaveVrayBaseBSDF *bsdf = _bsdfPool().newBRDF(rc);
+ //if (!bsdf)
+ // return NULL;
+
+ //int strandIdx = rc.rayresult.faceIndex;
+ //VR::Color diffCol = VR::Color(0.0f, 1.0f, 0.0f); //just green to see if somthing goes wrong
+
+ //int segmentIdx=(int) rc.rayresult.extraf;
+
+ //if(prim()->IsColorConst(strandIdx))
+ // prim()->GetRootColor(strandIdx,diffCol);
+ //else
+ // prim()->GetInterpColor(segmentIdx, strandIdx,diffCol);
+
+ //VR::Color specCol = VR::Color(1.0f, 1.0f, 1.0f);
+
+ //float opacity = 1.0f;
+ //if(prim()->GetTipFade())
+ // opacity = prim()->GetInterpOpacity(segmentIdx,strandIdx);
+ //else
+ // opacity = prim()->GetOpacity(strandIdx);
+ //
+ ////transparency
+ //float t=1.0f-opacity;
+ //VR::Color trsp = VR::Color(t, t, t);
+
+ ////ambient color [not used yet]
+ //VR::Color ambientCol = prim()->GetAmbient();
+
+ ////abient/diffuse factor
+ //float ambDiff = prim()->GetAmbDiff(strandIdx);
+
+ ////glossines
+ //float gloss = prim()->GetGlossiness(strandIdx);
+
+ //float splvl = prim()->GetSpecLevel(strandIdx);
+
+ //VR::Vector hairDir=prim()->GetHairDir(rc.rayresult.origPoint, segmentIdx, strandIdx);
+
+ //bsdf->init(rc,specCol,diffCol,ambientCol,ambDiff,splvl,gloss,0,trsp, hairDir, t);
+
+ //return bsdf;
+#endif
+}
+
+void shaveVrayTriShadeable::deleteBSDF(const VR::VRayContext &rc, VR::BSDFSampler *bsdf)
+{
+ if(!bsdf)
+ return;
+#ifdef USE_WHITE_TRI_BRDF
+ VR::WhiteBRDF *dbsdf = static_cast<VR::WhiteBRDF*>(bsdf);
+#else
+ #error not implemented
+ //shaveVrayBaseBSDF* dbsdf = static_cast<shaveVrayBaseBSDF*>(bsdf);
+#endif
+ _bsdfPool().deleteBRDF(rc, dbsdf);
+}
+
+#if defined(VRAY40)
+int shaveVrayTriShadeable::getBSDFFlags()
+{
+ return VR::bsdfFlag_none;
+}
+#endif
+
+void shaveVrayTriShadeable::initBSDFpool(VR::VRayCore *vray)
+{
+ const VR::VRaySequenceData &sdata=vray->getSequenceData();
+ _bsdfPool().init(sdata.maxRenderThreads);
+}
+
+void shaveVrayTriShadeable::freeBSDFpool()
+{
+ _bsdfPool().freeMem();
+}
diff --git a/vrayPlug/plugin/shaveVrayTriShadeable.h b/vrayPlug/plugin/shaveVrayTriShadeable.h
new file mode 100644
index 0000000..3164801
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriShadeable.h
@@ -0,0 +1,93 @@
+#ifndef _HAIR_VR_tri_SHADEABLE_H_
+#define _HAIR_VR_tri_SHADEABLE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayTriShadeable.h
+
+ DESCRIPTION: Used by VRay to shade instanced surface
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 13-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "rayserver.h"
+#include "geometryclasses.h"
+#include "brdfs.h"
+#include "brdfpool.h"
+
+#include "shaveVrayTriVoxelPrim.h"
+//#include "shaveVrayBaseBSDF.h"
+
+#define USE_WHITE_TRI_BRDF
+
+class shaveVrayTriShadeable : public VR::BSDFShadeable {
+public:
+ shaveVrayTriShadeable(shaveVrayTriVoxelPrim* instanced);
+ ~shaveVrayTriShadeable();
+ /*
+ | from Shadeable
+ */
+ // This is called to shade the intersection in the rayresult member of the given context.
+ void shade(VR::VRayContext &rc);
+
+ //Returns the name of the shadeable; used to print warnings if any shading errors occur.
+ tchar* getName(VR::VRayContext &rc);
+
+ /*
+ |
+ */
+ VR::BSDFSampler* newBSDF (const VR::VRayContext &rc, VR::BSDFFlags flags);
+
+ void deleteBSDF(const VR::VRayContext &rc, VR::BSDFSampler *bsdf);
+
+ /*
+ | own
+ */
+ void initBSDFpool(VR::VRayCore *vray);
+
+ void freeBSDFpool();
+
+#if defined VRAY40
+ int getBSDFFlags() VRAY_OVERRIDE;
+#endif
+
+protected:
+ //const member access
+#ifdef USE_WHITE_TRI_BRDF
+ inline const VR::BRDFPool<VR::WhiteBRDF>& bsdfPool() const {return m_bsdfPool;}
+#else
+ inline const VR::BRDFPool<shaveVrayBaseBSDF>& bsdfPool() const {return m_bsdfPool;}
+#endif
+ inline shaveVrayTriVoxelPrim* prim() const {return m_prim;}
+
+ //const member access
+#ifdef USE_WHITE_TRI_BRDF
+ inline VR::BRDFPool<VR::WhiteBRDF>& _bsdfPool() {return m_bsdfPool;}
+#else
+ inline VR::BRDFPool<shaveVrayBaseBSDF>& _bsdfPool() {return m_bsdfPool;}
+#endif
+ inline shaveVrayTriVoxelPrim*& _prim() {return m_prim;}
+
+protected:
+#ifdef USE_WHITE_TRI_BRDF
+ VR::BRDFPool<VR::WhiteBRDF> m_bsdfPool;
+#else
+ VR::BRDFPool<shaveVrayBaseBSDF> m_bsdfPool;
+#endif
+
+ shaveVrayTriVoxelPrim* m_prim;
+};
+
+#endif //end of_HAIR_VR_tri_SHADEABLE_H_
diff --git a/vrayPlug/plugin/shaveVrayTriVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayTriVoxelPrim.cpp
new file mode 100644
index 0000000..69d0de4
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriVoxelPrim.cpp
@@ -0,0 +1,42 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayTriVoxelPrim.cpp
+
+ DESCRIPTION: Generic instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 13-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayTriVoxelPrim.h"
+#include "shaveVrayTriShadeable.h"
+//#include "shaveVrayShadeData.h"
+#include "shaveVrayInstanceI.h"
+
+shaveVrayTriVoxelPrim::shaveVrayTriVoxelPrim(IHairVoxel* vox, VR::VRayCore* vray,
+ shaveVrayInstanceI* inst):
+ shaveVrayVoxelPrimBase(vox,vray)
+{
+ _hinst() = inst;
+
+ shaveVrayTriShadeable* sh = new shaveVrayTriShadeable(this);
+ if(vray)
+ {
+ sh->initBSDFpool(vray);
+ }
+ _shade() = sh;
+ _shdata() = new shaveVrayTriShadeData(hinst());
+}
+shaveVrayTriVoxelPrim::~shaveVrayTriVoxelPrim()
+{
+ if(shade())
+ delete shade();
+}
diff --git a/vrayPlug/plugin/shaveVrayTriVoxelPrim.h b/vrayPlug/plugin/shaveVrayTriVoxelPrim.h
new file mode 100644
index 0000000..f68c981
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayTriVoxelPrim.h
@@ -0,0 +1,60 @@
+#ifndef _HAIR_VR_tri_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_tri_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayTriVoxelPrim.h
+
+ DESCRIPTION: Generic instanced hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010
+
+ *>
+ **********************************************************************/
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "rayserver.h"
+#include "geometryclasses.h"
+
+#include "hairAPIvrayutil.h"
+#include "shaveVrayTriShadeData.h"
+#include "shaveVrayVoxelPrimBase.h"
+
+class shaveVrayInstanceI;
+
+//#define OWN_SHADEABLE_FOR_TRI
+
+class shaveVrayTriVoxelPrim : public shaveVrayVoxelPrimBase {
+public:
+ shaveVrayTriVoxelPrim(IHairVoxel* vox, VR::VRayCore* vray, shaveVrayInstanceI* inst);
+ virtual ~shaveVrayTriVoxelPrim();
+
+protected:
+
+ //const member access
+ inline shaveVrayInstanceI* hinst() const {return m_hinst;}
+ inline VR::Shadeable* shade() const {return m_shade;}
+ inline shaveVrayTriShadeData* shdata() const {return m_shdata;}
+
+ //member access
+ inline shaveVrayInstanceI*& _hinst() {return m_hinst;}
+ inline VR::Shadeable*& _shade() {return m_shade;}
+ inline shaveVrayTriShadeData*& _shdata() {return m_shdata;}
+
+private:
+
+ shaveVrayInstanceI* m_hinst;
+ VR::Shadeable* m_shade;
+ shaveVrayTriShadeData* m_shdata;
+};
+
+#endif //end of_HAIR_VR_tri_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/shaveVrayVoxelPrim.cpp b/vrayPlug/plugin/shaveVrayVoxelPrim.cpp
new file mode 100644
index 0000000..2e6cd2b
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayVoxelPrim.cpp
@@ -0,0 +1,279 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayVoxelPrim.cpp ( was shaveVrayVoxelPrim.cpp ) -- implementation file
+
+ DESCRIPTION: Generic hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 02-09-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 30-03-2010
+
+ *>
+ **********************************************************************/
+
+#include "assert.h"
+#include "shaveVrayVoxelPrim.h"
+//#include "shaveVrayPrimsSharedFunctions.h"
+#include "shaveVrayShadeable.h"
+#include "shaveVrayShadeInstance.h"
+#include "shaveVrayShadeData.h"
+#include "shaveVrayInstance.h"
+
+
+shaveVrayVoxelPrim::shaveVrayVoxelPrim(IHairVoxel* vox,
+ VR::VRayCore *vray,
+ shaveVrayInstance *inst):
+ shaveVrayVoxelPrimBase(vox,vray)
+{
+ _hinst() = inst;
+ _numknots() = eDefNumKnots;
+
+ for (int i=0; i < eNumSides; i++)
+ {
+ float angle=2.0f*VR::pi()*float(i)/float(eNumSides);
+ _uc(i)=cosf(angle);
+ _vc(i)=sinf(angle);
+ }
+
+ if(voxel())
+ {
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+ if(numHairs == 0)
+ {
+ //assume all hairs have the same number of segments
+ _numknots() = hair.face_end[0] - hair.face_start[0];
+ }
+ }
+
+ shaveVrayShadeable* sh = new shaveVrayShadeable(this);
+ if(vray)
+ {
+ sh->initBSDFpool(vray);
+ }
+ _shade() = sh;
+
+ //_shinst() = new shaveVrayShadeInstance<moving>(this);
+ _shinst() = (VR::VRayShadeInstance*) new shaveVrayShadeInstance(this);
+
+// _shdata() = new HairVrShadeData();
+
+ //_shdata() = new shaveVrayShadeData(hinst());
+ _shdata() = inst->GetShData();
+
+// _sfprops() = new VR::SurfaceProperties;
+
+ _tipfade() = false;
+}
+
+shaveVrayVoxelPrim::~shaveVrayVoxelPrim()
+{
+ if(shade())
+ delete shade();
+
+ if(shinst())
+ delete shinst();
+
+ //if(shdata())
+ // delete shdata();
+
+ //if(sfprops())
+ // delete sfprops();
+}
+
+bool shaveVrayVoxelPrim::IsColorConst(int strandidx) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.IsColorConst(strandidx);
+}
+
+void shaveVrayVoxelPrim::GetRootColor(int strandidx,VR::Color& c) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.GetRootColor(strandidx,c.r,c.g,c.b);
+}
+
+float shaveVrayVoxelPrim::GetOpacity(int strandidx) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.GetStrandOpacity(strandidx);
+}
+
+float shaveVrayVoxelPrim::GetAmbDiff(int strandidx) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.GetStrandAmbDiff(strandidx);
+}
+
+float shaveVrayVoxelPrim::GetGlossiness(int strandidx) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.GetStrandGlossiness(strandidx);
+}
+
+float shaveVrayVoxelPrim::GetSpecLevel(int strandidx) const
+{
+ const HairType& hair = voxel()->GetHair();
+ return hair.GetStrandSpecLevel(strandidx);
+}
+
+VR::ShadeVec shaveVrayVoxelPrim::GetUVW(int segmentIdx, int strandidx, float segmentOffset, int channel) const {
+#if 0 //vlad|22jan2013 - we still do not have valid data in UVSETS
+ const HairUVs& hairUVs=voxel()->GetUVs();
+
+ if (channel<0 || channel>=hairUVs.totalUVSets)
+ return VR::Vector(0.0f, 0.0f, 0.0f);
+
+ if (strandidx<0 || strandidx>=hairUVs.totalRoots)
+ return VR::Vector(0.0f, 0.0f, 0.0f);
+
+ const VERT &uv=hairUVs.uvRoot[strandidx*hairUVs.totalUVSets+channel];
+ return VR::Vector(uv.x, uv.y, uv.z);
+
+#else //grabbing it form defaut set of HAIRTYPE
+
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if (strandidx >= numHairs || strandidx < 0)
+ return VR::ShadeVec(0.0f, 0.0f, 0.0f);
+
+ int start;
+ int end;
+ hair.GetStrand(strandidx, start, end);
+
+ int numKnots=end-start;
+ if (segmentIdx<0 || segmentIdx>=numKnots-1)
+ return VR::ShadeVec(0.0f, 0.0f, 0.0f);
+
+ VR::ShadeVec uvw0;
+ VR::ShadeVec uvw1;
+
+ int min_i=segmentIdx+start;
+ GetUV(hair, min_i+0, uvw0);
+ GetUV(hair, min_i+1, uvw1);
+
+ return uvw0+(uvw1-uvw0)*segmentOffset;
+
+#endif
+}
+
+//not optimized routine
+void shaveVrayVoxelPrim::GetInterpColor(int segmentIdx, int strandidx, float segmentOffset, VR::Color& res) const
+{
+ ///////////// test ///////////
+ //res = VR::Color(1.0f, 0.0f, 0.0f);
+ //return;
+ //////////////////////////////
+
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(strandidx >= numHairs || strandidx < 0)
+ {
+ //red hair will be a signal that something goes wrong
+ res = VR::Color(1.0f, 0.0f, 0.0f);
+ return;
+ }
+ int start;
+ int end;
+ hair.GetStrand(strandidx,start,end);
+ int nknots = end - start;
+
+ float t=segmentOffset;
+
+ float T=(float) (segmentIdx);
+ float d=(T+t)/(float) nknots;
+
+ hair.GetColor(strandidx,d,res.r,res.g,res.b);
+}
+
+//not optimized routine
+float shaveVrayVoxelPrim::GetInterpOpacity(int segmentIdx, int strandidx, float segmentOffset) const
+{
+ ///////////// test /////////
+ //return 1.0f;
+ ///////////////////////////
+
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(strandidx >= numHairs || strandidx < 0)
+ {
+ return 1.0f;
+ }
+ int start;
+ int end;
+ hair.GetStrand(strandidx,start,end);
+ int nknots = end - start;
+
+ float t=segmentOffset;
+
+ float T=(float) (segmentIdx);
+ float d=(T+t)/(float) nknots;
+
+ if(d > 1.0f)
+ d = 1.0f;
+
+ if(d < 0.0f)
+ d = 0.0f;
+
+ float op = hair.GetStrandOpacity(strandidx);
+ return op*(1.0f-d);
+}
+
+VR::ShadeVec shaveVrayVoxelPrim::GetHairDir(const VR::ShadeVec &hit, int segmentIdx, int strandidx, float segmentOffset) const
+{
+ //////////// test ////////////
+ //return VR::Vector(0.0f, 0.0f, 1.0f);
+ ////////////////////////////
+
+ const HairType& hair = voxel()->GetHair();
+ int numHairs = hair.GetNumStrands();
+
+ if(strandidx >= numHairs || strandidx < 0)
+ {
+ return VR::ShadeVec(0.0f, 0.0f, 1.0f);
+ }
+ int start;
+ int end;
+ hair.GetStrand(strandidx,start,end);
+ int nknots = end - start;
+
+ VR::ShadeVec knot0;
+ VR::ShadeVec knot1;
+ int min_i=segmentIdx+start;
+
+ GetVert(hair, min_i, knot0);
+ GetVert(hair, min_i+1, knot1);
+ VR::ShadeVec sg = knot1 - knot0;
+
+ float t=segmentOffset;
+ float T=(float) (segmentIdx);
+ float d=(T+t)/(float) nknots;
+
+ float sgLen=sg.length();
+ VR::ShadeVec dir1=(sgLen<1e-12f)? VR::ShadeVec(0.0f, 0.0f, 0.0f) : (sg/sg.length()); // The direction of the current segment
+
+ VR::ShadeVec dir0; // The direction of the previous segment
+ if (min_i-1-start<0) {
+ GetSurfNormal(hair, strandidx, dir0);
+ dir0.makeNormalized0();
+ } else {
+ VR::ShadeVec knotb;
+ GetVert(hair, min_i-1, knotb);
+ dir0=knot0-knotb;
+ dir0.makeNormalized0();
+ }
+
+ dir0+=(dir1-dir0)*t;
+ dir0.makeNormalized0();
+ return dir0;
+ //return VR::normalize0(dir0+(dir1-dir0)*t);
+}
+
diff --git a/vrayPlug/plugin/shaveVrayVoxelPrim.h b/vrayPlug/plugin/shaveVrayVoxelPrim.h
new file mode 100644
index 0000000..b946e40
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayVoxelPrim.h
@@ -0,0 +1,167 @@
+#ifndef _HAIR_VR_VOXEL_PRIMITIVE_H_
+#define _HAIR_VR_VOXEL_PRIMITIVE_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayVoxelPrim.h (was shaveVrayVoxelPrim.h)
+
+ DESCRIPTION: Generic hair voxel primitive
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 02-09-2008 ( as part of 3ds Max + VRay hair shaders)
+ merged 30-03-2010
+
+ *>
+ **********************************************************************/
+
+////#include <max.h> //VRayInterface needs it - ShadeContext
+//#include <vraybase.h>
+////#include <vrayinterface.h>
+//#include <rayprimitives.h>
+//#include <hairprimitives.h>
+//#include <vraygeom.h>
+//#include <pool.h>
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "rayserver.h"
+#include "geometryclasses.h"
+
+#ifdef VRAY20
+#include "pool.h"
+#endif
+
+#include "hairAPIvrayutil.h"
+#include "shaveVrayShadeData.h"
+#include "shaveVrayVoxelPrimBase.h"
+
+class shaveVrayInstance;
+
+class shaveVrayVoxelPrim : public shaveVrayVoxelPrimBase {
+public:
+ shaveVrayVoxelPrim(IHairVoxel* vox, VR::VRayCore* vray, shaveVrayInstance* inst);
+ virtual ~shaveVrayVoxelPrim();
+
+ enum consts
+ {
+ eNumSides = 4, //always 4
+ eDefNumKnots = 5 //actual value from HairType should be used
+ };
+
+ void SetTipFade(bool set){ _tipfade() = set;}
+ bool GetTipFade() const {return tipfade();}
+
+ void SetUseOwnBSDF(bool set){ _ownbsdf() = set;}
+ bool GetUseOwnBSDF() const {return ownbsdf();}
+
+ void SetAmbient(const VR::Color& c) {_ambient() = c;}
+ const VR::Color& GetAmbient() const {return ambient();}
+
+ const VR::Color& GetSpecTint() const {return spectint();}
+ void SetSpecTint(const VR::Color& c) {_spectint() = c;}
+
+ const VR::Color& GetSpecTint2() const {return spectint2();}
+ void SetSpecTint2(const VR::Color& c) {_spectint2() = c;}
+
+ bool IsColorConst(int strandidx) const;
+ void GetRootColor(int strandidx,VR::Color& c) const;
+ void GetInterpColor(int segmentIdx, int strandidx, float segmentOffset, VR::Color& res) const;
+ float GetInterpOpacity(int segmentIdx, int strandidx, float segmentOffset) const;
+ float GetOpacity (int strandidx) const;
+ float GetAmbDiff (int strandidx) const;
+ float GetGlossiness(int strandidx) const;
+ float GetSpecLevel (int strandidx) const;
+
+
+ VR::ShadeVec GetHairDir(const VR::ShadeVec& hit, int segmentIdx, int strandidx, float segmentOffset) const;
+ VR::ShadeVec GetUVW(int segmentIdx, int strandIdx, float segmentOffset, int channel) const;
+
+ inline shaveVrayInstance* GetInstance() const {return hinst();}
+
+#if defined(VRAY30) || defined(VRAY40)
+ virtual VR::ShadeVec getHairDir(const VR::VRayContext &rc) const=0;
+#endif
+protected:
+
+ //const member access
+ inline VR::Shadeable* shade() const {return m_shade;}
+ inline VR::VRayShadeInstance* shinst() const {return m_shinst;}
+ //inline VR::VRayShadeData* shdata() const {return m_shdata;}
+ //inline VR::BaseMeshShadeData/*<moving>*/* shdata() const {return m_shdata;}
+ inline shaveVrayShadeData* shdata() const {return m_shdata;}
+ inline shaveVrayInstance* hinst() const {return m_hinst;}
+ //inline VR::SurfaceProperties* sfprops() const {return m_sfprops;}
+#if defined(VRAY20) || defined(VRAY30) || defined(VRAY40)
+ inline const VR::FixedPool<true>& pool_Vector() const {return m_pool_Vector;}
+#else
+ inline const VR::FixedPool& pool_Vector() const {return m_pool_Vector;}
+#endif
+ inline const VR::Color& ambient() const {return m_ambient;}
+ inline const VR::Color& spectint() const {return m_spectint;}
+ inline const VR::Color& spectint2() const {return m_spectint2;}
+ inline int numknots()const {return m_numknots;}
+ inline float uc(int i) const {return m_uc[i];}
+ inline float vc(int i) const {return m_vc[i];}
+ inline bool tipfade() const {return m_tipfade;}
+ inline bool ownbsdf() const {return m_ownbsdf;}
+
+ //ptr access
+ inline const float* puc() const {return m_uc;}
+ inline const float* pvc() const {return m_vc;}
+ inline float* _puc() {return m_uc;}
+ inline float* _pvc() {return m_vc;}
+
+ //member access
+ inline VR::Shadeable*& _shade() {return m_shade;}
+ inline VR::VRayShadeInstance*& _shinst() {return m_shinst;}
+ //inline VR::VRayShadeData*& _shdata() {return m_shdata;}
+ inline shaveVrayShadeData*& _shdata() {return m_shdata;}
+ inline shaveVrayInstance*& _hinst() {return m_hinst;}
+ //inline VR::BaseMeshShadeData/*<moving>*/*& _shdata() {return m_shdata;}
+ //inline VR::SurfaceProperties*& _sfprops() {return m_sfprops;}
+#if defined(VRAY20) || defined(VRAY30) || defined(VRAY40)
+ inline VR::FixedPool<true>& _pool_Vector() {return m_pool_Vector;}
+#else
+ inline VR::FixedPool& _pool_Vector() {return m_pool_Vector;}
+#endif
+ inline VR::Color& _ambient() {return m_ambient;}
+ inline VR::Color& _spectint() {return m_spectint;}
+ inline VR::Color& _spectint2() {return m_spectint2;}
+ inline int& _numknots() {return m_numknots;}
+ inline float& _uc(int i) {return m_uc[i];}
+ inline float& _vc(int i) {return m_vc[i];}
+ inline bool& _tipfade() {return m_tipfade;}
+ inline bool& _ownbsdf() {return m_ownbsdf;}
+
+private:
+
+ int m_numknots;
+ bool m_tipfade;
+ bool m_ownbsdf;
+ float m_uc[eNumSides];
+ float m_vc[eNumSides];
+ VR::Color m_ambient;
+ VR::Color m_spectint;
+ VR::Color m_spectint2;
+#if defined(VRAY20) || defined(VRAY30) || defined(VRAY40)
+ VR::FixedPool<true> m_pool_Vector;
+#else
+ VR::FixedPool m_pool_Vector;
+#endif
+ VR::Shadeable* m_shade;
+ VR::VRayShadeInstance* m_shinst; //3ds Max related
+ //VR::VRayShadeData* m_shdata; //3ds Max related
+ //VR::BaseMeshShadeData/*<moving>*/* m_shdata;
+ shaveVrayShadeData* m_shdata;
+ shaveVrayInstance* m_hinst;
+ //VR::SurfaceProperties* m_sfprops; //3ds Max related
+};
+
+#endif //end of_HAIR_VR_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/shaveVrayVoxelPrimBase.h b/vrayPlug/plugin/shaveVrayVoxelPrimBase.h
new file mode 100644
index 0000000..687a302
--- /dev/null
+++ b/vrayPlug/plugin/shaveVrayVoxelPrimBase.h
@@ -0,0 +1,75 @@
+#ifndef _HAIR_VR_VOXEL_PRIMITIVE_base_H_
+#define _HAIR_VR_VOXEL_PRIMITIVE_base_H_
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+/**********************************************************************
+ *<
+ FILE: shaveVrayVoxelPrimBase.h
+
+ DESCRIPTION: Generic base class for all voxel primitive classes
+
+ CREATED BY: Vladimir Dubovoy <[email protected]>
+
+ HISTORY: created 12-05-2010 ( as part of 3ds Max + VRay hair shaders)
+
+ *>
+ **********************************************************************/
+
+#include "utils.h"
+#include "box.h"
+#include "rayserver.h"
+#include "vrayplugins.h"
+#include "rayserver.h"
+#include "geometryclasses.h"
+
+#include "hairAPIvrayutil.h"
+#include "assert.h"
+
+class shaveVrayVoxelPrimBase {
+public:
+ shaveVrayVoxelPrimBase(IHairVoxel* vox, VR::VRayCore* vray)
+ {
+ assert(vox);
+ _voxel() = vox;
+
+ vrayCore = vray;
+
+ if(vray)
+ {
+ const VR::VRayFrameData& vrfd = vray->getFrameData();
+ _sceneOffset() = vrfd.sceneOffset;
+ }
+ }
+ virtual ~shaveVrayVoxelPrimBase(){}
+
+ inline IHairVoxel* GetVoxel() const {return voxel();}
+
+protected:
+
+ VR::VRayCore* vrayCore;
+
+ //const member access
+ inline const VR::TracePoint& sceneOffset() const {return m_sceneOffset;}
+ inline IHairVoxel* voxel() const {return m_voxel;}
+
+ //member access
+ inline VR::TracePoint& _sceneOffset() {return m_sceneOffset;}
+public:
+ inline IHairVoxel*& _voxel(){return m_voxel;}
+
+private:
+
+ IHairVoxel* m_voxel;
+ //got form VRayFrameData::sceneOffset - it should be added to shaded points rc.rayresult.wpoint
+ //
+ //In versions of the V-Ray SDK prior to 1.90.00, wpoint was directly in world space.
+ //In versions 1.90.00 and later, the actual world-space coordinates can be obtained
+ //by adding VRayFrameData::sceneOffset to the wpoint.
+ VR::TracePoint m_sceneOffset ;
+
+};
+
+#endif //end of_HAIR_VR_VOXEL_PRIMITIVE_H_
diff --git a/vrayPlug/plugin/vray3_compat.h b/vrayPlug/plugin/vray3_compat.h
new file mode 100644
index 0000000..14ca436
--- /dev/null
+++ b/vrayPlug/plugin/vray3_compat.h
@@ -0,0 +1,132 @@
+#ifndef __VRAY3_COMPAT_H__
+#define __VRAY3_COMPAT_H__
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#pragma once
+
+#include <vraybase.h>
+#include <vrayinterface.h>
+
+#if !defined VRAY_OVERRIDE
+#define VRAY_OVERRIDE
+#endif
+
+#if VRAY_DLL_VERSION >= 0x30000
+
+#if !defined SHADEVEC_IS_VECTOR3F && !defined SHADEVEC_IS_VECTOR
+
+namespace VUtils {
+
+// This is V-Ray 3.x SDK and we need to define some missing types.
+typedef Vector ShadeVec;
+typedef Transform ShadeTransform;
+typedef Matrix ShadeMatrix;
+
+FORCEINLINE ShadeVec toShadeVec(const Vector& v) { return v; }
+FORCEINLINE ShadeVec toShadeVec(const TracePoint &v) { return ShadeVec(v.x, v.y, v.z); }
+
+FORCEINLINE ShadeMatrix toShadeMatrix(const Matrix &m) { return m; }
+
+FORCEINLINE ShadeTransform toShadeTransform(const Transform &m) { return m; }
+FORCEINLINE ShadeTransform toShadeTransform(const TraceTransform &m) {
+ Transform res;
+ res.m[0]=m.m[0];
+ res.m[1]=m.m[1];
+ res.m[2]=m.m[2];
+ res.offs=ShadeVec(m.offs.x, m.offs.y, m.offs.z);
+ return res;
+}
+
+FORCEINLINE Vector toVector(const ShadeVec& v) { return v; }
+FORCEINLINE Color toColor(const ShadeVec& v) { return Color(v.x, v.y, v.z); }
+FORCEINLINE Transform toTransform(const ShadeTransform &tm) { return tm; }
+FORCEINLINE TraceTransform toTraceTransform(const ShadeTransform &tm) { return TraceTransform(tm); }
+FORCEINLINE Matrix toMatrix(const ShadeMatrix &m) { return m; }
+
+FORCEINLINE Transform toTransform(const TraceTransform &tm) {
+ Transform res;
+ res.m=tm.m;
+ res.offs.set(VUtils::real(tm.offs.x), VUtils::real(tm.offs.y), VUtils::real(tm.offs.z));
+ return res;
+}
+
+FORCEINLINE float x(const Vector& v) { return v.x; }
+FORCEINLINE float y(const Vector& v) { return v.y; }
+FORCEINLINE float z(const Vector& v) { return v.z; }
+
+} // namespace VUtils
+
+#endif // !defined SHADEVEC_IS_VECTOR3F && !defined SHADEVEC_IS_VECTOR
+
+#if !defined SHADECOL_IS_COLOR3F && !defined SHADECOL_IS_COLOR
+
+namespace VUtils {
+
+typedef Color ShadeCol;
+typedef AColor ShadeACol;
+
+FORCEINLINE ShadeCol toShadeCol(const Color &col) { return col; }
+FORCEINLINE ShadeACol toShadeACol(const AColor &col) { return col; }
+
+FORCEINLINE Color toColor(const ShadeCol &col) { return col; }
+FORCEINLINE AColor toAColor(const ShadeACol &col) { return col; }
+
+FORCEINLINE float red(const Color &v) { return v.r; }
+FORCEINLINE float green(const Color &v) { return v.g; }
+FORCEINLINE float blue(const Color &v) { return v.b; }
+
+FORCEINLINE void setComponent(Color &c, int i, float f) { c[i]=f; }
+
+} // namespace VUtils
+
+#endif // !defined SHADEVEC_IS_VECTOR3F && !defined SHADEVEC_IS_VECTOR
+
+namespace VUtils {
+
+#ifdef VRAY_RAYFLAGS_ARE_64BITS
+typedef VUtils::RayFlags VRayRayFlags;
+#else
+typedef int VRayRayFlags;
+const VRayRayFlags RT_NONE=0;
+#endif
+
+
+} // namespace VUtils
+
+#endif // VRAY_DLL_VERSION >= 0x30000
+
+// utility fastfinite functions
+namespace VUtils {
+#if VRAY_DLL_VERSION >= 0x40000
+FORCEINLINE int hasNonFiniteLanes(const Vector &v) {
+ return v.hasNonFiniteLanes();
+}
+FORCEINLINE int hasNonFiniteLanes(const Color &v) {
+ return !(fastfinite(v.r) && fastfinite(v.g) && fastfinite(v.b));
+}
+FORCEINLINE int hasNonFiniteLanes(const simd::Vector3f &v) {
+ return v.hasNonFiniteLanes();
+}
+FORCEINLINE int hasNonFiniteLanes(const simd::Color3f &v) {
+ return toVector3f(v).hasNonFiniteLanes();
+}
+FORCEINLINE Vector toVector(const TracePoint &v) {
+ return v.toVector();
+}
+#else
+FORCEINLINE int hasNonFiniteLanes(const Vector &v) {
+ return !(fastfinite(v.x) && fastfinite(v.y) && fastfinite(v.z));
+}
+FORCEINLINE int hasNonFiniteLanes(const Color &v) {
+ return !(fastfinite(v.r) && fastfinite(v.g) && fastfinite(v.b));
+}
+FORCEINLINE Vector toVector(const TracePoint &v) {
+ return Vector(float(v.x), float(v.y), float(v.z));
+}
+#endif
+} // namespace VUtils
+
+#endif // __VRAY3_COMPAT_H__