1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "Material/MaterialManager.h"
5 #include "Material/MaterialHelpers.h"
6 #include "Util/BoostPythonHelpers.h"
7 #include "Util/MFCUtil.h"
11 void PyMaterialCreate()
13 GetIEditorImpl()->GetMaterialManager()->Command_Create();
16 void PyMaterialCreateMulti()
18 GetIEditorImpl()->GetMaterialManager()->Command_CreateMulti();
21 void PyMaterialConvertToMulti()
23 GetIEditorImpl()->GetMaterialManager()->Command_ConvertToMulti();
26 void PyMaterialDuplicateCurrent()
28 GetIEditorImpl()->GetMaterialManager()->Command_Duplicate();
31 void PyMaterialMergeSelection()
33 GetIEditorImpl()->GetMaterialManager()->Command_Merge();
36 void PyMaterialDeleteCurrent()
38 GetIEditorImpl()->GetMaterialManager()->Command_Delete();
41 void PyCreateTerrainLayer()
43 GetIEditorImpl()->GetMaterialManager()->Command_CreateTerrainLayer();
46 void PyMaterialAssignCurrentToSelection()
48 CUndo
undo("Assign Material To Selection");
49 GetIEditorImpl()->GetMaterialManager()->Command_AssignToSelection();
52 void PyMaterialResetSelection()
54 GetIEditorImpl()->GetMaterialManager()->Command_ResetSelection();
57 void PyMaterialSelectObjectsWithCurrent()
59 CUndo
undo("Select Objects With Current Material");
60 GetIEditorImpl()->GetMaterialManager()->Command_SelectAssignedObjects();
63 void PyMaterialSetCurrentFromObject()
65 GetIEditorImpl()->GetMaterialManager()->Command_SelectFromObject();
68 std::vector
<std::string
> PyGetSubMaterial(const char* pMaterialPath
)
70 string materialPath
= pMaterialPath
;
71 CMaterial
* pMaterial
= GetIEditorImpl()->GetMaterialManager()->LoadMaterial(pMaterialPath
, false);
74 throw std::runtime_error("Invalid multi material.");
77 std::vector
<std::string
> result
;
78 for (int i
= 0; i
< pMaterial
->GetSubMaterialCount(); i
++)
80 if (pMaterial
->GetSubMaterial(i
))
82 result
.push_back(static_cast<std::string
>(materialPath
+ "\\" + pMaterial
->GetSubMaterial(i
)->GetName()));
88 CMaterial
* TryLoadingMaterial(const char* pPathAndMaterialName
)
90 CString varMaterialPath
= pPathAndMaterialName
;
91 std::deque
<string
> splittedMaterialPath
;
93 for (string token
= varMaterialPath
.Tokenize("/\\", currentPos
); !token
.IsEmpty(); token
= varMaterialPath
.Tokenize("/\\", currentPos
))
95 splittedMaterialPath
.push_back(token
);
98 CMaterial
* pMaterial
= GetIEditorImpl()->GetMaterialManager()->LoadMaterial(varMaterialPath
, false);
101 string subMaterialName
= splittedMaterialPath
.back();
102 bool isSubMaterialExist(false);
104 varMaterialPath
.Delete((varMaterialPath
.GetLength() - subMaterialName
.GetLength() - 1), varMaterialPath
.GetLength());
105 string test
= varMaterialPath
;
106 pMaterial
= GetIEditorImpl()->GetMaterialManager()->LoadMaterial(varMaterialPath
, false);
110 throw std::runtime_error("Invalid multi material.");
113 for (int i
= 0; i
< pMaterial
->GetSubMaterialCount(); i
++)
115 if (pMaterial
->GetSubMaterial(i
)->GetName() == subMaterialName
)
117 pMaterial
= pMaterial
->GetSubMaterial(i
);
118 isSubMaterialExist
= true;
122 if (!pMaterial
|| !isSubMaterialExist
)
124 throw std::runtime_error(string("\"") + subMaterialName
+ "\" is an invalid sub material.");
127 GetIEditorImpl()->GetMaterialManager()->SetCurrentMaterial(pMaterial
);
131 std::deque
<string
> PreparePropertyPath(const char* pPathAndPropertyName
)
133 string varPathProperty
= pPathAndPropertyName
;
134 std::deque
<string
> splittedPropertyPath
;
136 for (string token
= varPathProperty
.Tokenize("/\\", currentPos
); !token
.IsEmpty(); token
= varPathProperty
.Tokenize("/\\", currentPos
))
138 splittedPropertyPath
.push_back(token
);
141 return splittedPropertyPath
;
144 //////////////////////////////////////////////////////////////////////////
145 // Converter: Enum -> string (human readable)
146 //////////////////////////////////////////////////////////////////////////
148 string
TryConvertingSEFResTextureToCString(SEfResTexture
* pResTexture
)
152 return pResTexture
->m_Name
.c_str();
157 string
TryConvertingETEX_TypeToCString(const uint8
& texTypeName
)
159 if (MaterialHelpers::IsTextureTypeExposed(texTypeName
))
161 return MaterialHelpers::GetNameFromTextureType(texTypeName
);
163 throw std::runtime_error("Invalid tex type.");
166 string
TryConvertingTexFilterToCString(const int& iFilterName
)
176 case FILTER_BILINEAR
:
178 case FILTER_TRILINEAR
:
181 return "Anisotropic 2x";
183 return "Anisotropic 4x";
185 return "Anisotropic 8x";
186 case FILTER_ANISO16X
:
187 return "Anisotropic 16x";
189 throw std::runtime_error("Invalid tex filter.");
193 string
TryConvertingETexGenTypeToCString(const uint8
& texGenType
)
204 throw std::runtime_error("Invalid tex gen type.");
208 string
TryConvertingETexModRotateTypeToCString(const uint8
& rotateType
)
215 return "Fixed Rotation";
217 return "Constant Rotation";
218 case ETMR_Oscillated
:
219 return "Oscillated Rotation";
221 throw std::runtime_error("Invalid rotate type.");
225 string
TryConvertingETexModMoveTypeToCString(const uint8
& oscillatorType
)
227 switch (oscillatorType
)
232 return "Fixed Moving";
234 return "Constant Moving";
236 return "Jitter Moving";
240 return "Stretch Moving";
241 case ETMM_StretchRepeat
:
242 return "Stretch-Repeat Moving";
244 throw std::runtime_error("Invalid oscillator type.");
248 string
TryConvertingEDeformTypeToCString(const EDeformType
& deformType
)
256 case eDT_SinWaveUsingVtxColor
:
257 return "Sin Wave using vertex color";
267 return "From Center";
271 return "Proc. Flare";
273 return "Auto sprite";
276 case eDT_FixedOffset
:
277 return "FixedOffset";
279 throw std::runtime_error("Invalid deform type.");
283 string
TryConvertingEWaveFormToCString(const EWaveForm
& waveForm
)
299 case eWF_InvSawTooth
:
300 return "Inverse Saw Tooth";
304 return "Inverse Hill";
306 throw std::runtime_error("Invalid wave form.");
310 //////////////////////////////////////////////////////////////////////////
311 // Converter: string -> Enum
312 //////////////////////////////////////////////////////////////////////////
314 EEfResTextures
TryConvertingCStringToEEfResTextures(const string
& resTextureName
)
316 if (resTextureName
== "Diffuse")
320 else if (resTextureName
== "Specular")
322 return EFTT_SPECULAR
;
324 else if (resTextureName
== "Bumpmap")
328 else if (resTextureName
== "Heightmap")
332 else if (resTextureName
== "Environment")
336 else if (resTextureName
== "Detail")
338 return EFTT_DETAIL_OVERLAY
;
340 else if (resTextureName
== "Opacity")
344 else if (resTextureName
== "Decal")
346 return EFTT_DECAL_OVERLAY
;
348 else if (resTextureName
== "SubSurface")
350 return EFTT_SUBSURFACE
;
352 else if (resTextureName
== "Custom")
356 else if (resTextureName
== "[1] Custom")
360 else if (resTextureName
== "Emittance")
362 return EFTT_EMITTANCE
;
364 throw std::runtime_error("Invalid texture name.");
367 ETEX_Type
TryConvertingCStringToETEX_Type(const string
& texTypeName
)
369 ETEX_Type texType
= (ETEX_Type
)MaterialHelpers::GetTextureTypeFromName(texTypeName
);
370 if (texType
== eTT_MaxTexType
|| !MaterialHelpers::IsTextureTypeExposed(texType
))
372 throw std::runtime_error("Invalid tex type name.");
377 signed char TryConvertingCStringToTexFilter(string filterName
)
379 if (filterName
== "Default")
383 else if (filterName
== "Point")
387 else if (filterName
== "Linear")
389 return FILTER_LINEAR
;
391 else if (filterName
== "Bi-linear")
393 return FILTER_BILINEAR
;
395 else if (filterName
== "Tri-linear")
397 return FILTER_TRILINEAR
;
399 else if (filterName
== "Anisotropic 2x")
401 return FILTER_ANISO2X
;
403 else if (filterName
== "Anisotropic 4x")
405 return FILTER_ANISO4X
;
407 else if (filterName
== "Anisotropic 8x")
409 return FILTER_ANISO8X
;
411 else if (filterName
== "Anisotropic 16x")
413 return FILTER_ANISO16X
;
415 throw std::runtime_error("Invalid filter name.");
418 ETexGenType
TryConvertingCStringToETexGenType(const string
& texGenType
)
420 if (texGenType
== "Stream")
424 else if (texGenType
== "World")
428 else if (texGenType
== "Camera")
432 throw std::runtime_error("Invalid tex gen type name.");
435 ETexModRotateType
TryConvertingCStringToETexModRotateType(const string
& rotateType
)
437 if (rotateType
== "No Change")
439 return ETMR_NoChange
;
441 else if (rotateType
== "Fixed Rotation")
445 else if (rotateType
== "Constant Rotation")
447 return ETMR_Constant
;
449 else if (rotateType
== "Oscillated Rotation")
451 return ETMR_Oscillated
;
453 throw std::runtime_error("Invalid rotate type name.");
456 ETexModMoveType
TryConvertingCStringToETexModMoveType(const string
& oscillatorType
)
458 if (oscillatorType
== "No Change")
460 return ETMM_NoChange
;
462 else if (oscillatorType
== "Fixed Moving")
466 else if (oscillatorType
== "Constant Moving")
468 return ETMM_Constant
;
470 else if (oscillatorType
== "Jitter Moving")
474 else if (oscillatorType
== "Pan Moving")
478 else if (oscillatorType
== "Stretch Moving")
482 else if (oscillatorType
== "Stretch-Repeat Moving")
484 return ETMM_StretchRepeat
;
486 throw std::runtime_error("Invalid oscillator type.");
489 EDeformType
TryConvertingCStringToEDeformType(const string
& deformType
)
491 if (deformType
== "None")
495 else if (deformType
== "Sin Wave")
499 else if (deformType
== "Sin Wave using vertex color")
501 return eDT_SinWaveUsingVtxColor
;
503 else if (deformType
== "Bulge")
507 else if (deformType
== "Squeeze")
511 else if (deformType
== "Perlin 2D")
515 else if (deformType
== "Perlin 3D")
519 else if (deformType
== "From Center")
521 return eDT_FromCenter
;
523 else if (deformType
== "Bending")
527 else if (deformType
== "Proc. Flare")
529 return eDT_ProcFlare
;
531 else if (deformType
== "Auto sprite")
533 return eDT_AutoSprite
;
535 else if (deformType
== "Beam")
539 else if (deformType
== "FixedOffset")
541 return eDT_FixedOffset
;
543 throw std::runtime_error("Invalid deform type.");
546 EWaveForm
TryConvertingCStringToEWaveForm(const string
& waveForm
)
548 if (waveForm
== "None")
552 else if (waveForm
== "Sin")
556 else if (waveForm
== "Half Sin")
560 else if (waveForm
== "Square")
564 else if (waveForm
== "Triangle")
568 else if (waveForm
== "Saw Tooth")
572 else if (waveForm
== "Inverse Saw Tooth")
574 return eWF_InvSawTooth
;
576 else if (waveForm
== "Hill")
580 else if (waveForm
== "Inverse Hill")
584 throw std::runtime_error("Invalid wave form.");
587 //////////////////////////////////////////////////////////////////////////
589 //////////////////////////////////////////////////////////////////////////
591 string
ParseUINameFromPublicParamsScript(const char* sUIScript
)
593 string uiscript
= sUIScript
;
596 string itemToken
= uiscript
.Tokenize(";", p1
);
597 while (!itemToken
.empty())
601 string token
= itemToken
.Tokenize(" \t\r\n=", p2
);
602 while (!token
.empty())
604 element
[nElements
++] = token
;
607 element
[nElements
] = itemToken
.substr(p2
);
608 element
[nElements
].Trim(" =\t\"");
611 token
= itemToken
.Tokenize(" \t\r\n=", p2
);
614 if (stricmp(element
[1], "UIName") == 0)
616 return element
[2].c_str();
618 itemToken
= uiscript
.Tokenize(";", p1
);
623 std::map
<string
, float> ParseValidRangeFromPublicParamsScript(const char* sUIScript
)
625 string uiscript
= sUIScript
;
626 std::map
<string
, float> result
;
627 bool isUIMinExist(false);
628 bool isUIMaxExist(false);
631 string itemToken
= uiscript
.Tokenize(";", p1
);
632 while (!itemToken
.empty())
636 string token
= itemToken
.Tokenize(" \t\r\n=", p2
);
637 while (!token
.empty())
639 element
[nElements
++] = token
;
642 element
[nElements
] = itemToken
.substr(p2
);
643 element
[nElements
].Trim(" =\t\"");
646 token
= itemToken
.Tokenize(" \t\r\n=", p2
);
649 if (stricmp(element
[1], "UIMin") == 0)
651 result
["UIMin"] = atof(element
[2]);
654 if (stricmp(element
[1], "UIMax") == 0)
656 result
["UIMax"] = atof(element
[2]);
659 itemToken
= uiscript
.Tokenize(";", p1
);
661 if (!isUIMinExist
|| !isUIMaxExist
)
663 throw std::runtime_error("Invalid range for shader param.");
668 //////////////////////////////////////////////////////////////////////////
670 //////////////////////////////////////////////////////////////////////////
672 void SetMaterialFlag(CMaterial
* pMaterial
, const EMaterialFlags
& eFlag
, const bool& bFlag
)
674 if (pMaterial
->GetFlags() & eFlag
&& bFlag
== false)
676 pMaterial
->SetFlags(pMaterial
->GetFlags() - eFlag
);
678 else if (!(pMaterial
->GetFlags() & eFlag
) && bFlag
== true)
680 pMaterial
->SetFlags(pMaterial
->GetFlags() | eFlag
);
684 void SetPropagationFlag(CMaterial
* pMaterial
, const eMTL_PROPAGATION
& eFlag
, const bool& bFlag
)
686 if (pMaterial
->GetPropagationFlags() & eFlag
&& bFlag
== false)
688 pMaterial
->SetPropagationFlags(pMaterial
->GetPropagationFlags() - eFlag
);
690 else if (!(pMaterial
->GetPropagationFlags() & eFlag
) && bFlag
== true)
692 pMaterial
->SetPropagationFlags(pMaterial
->GetPropagationFlags() | eFlag
);
696 //////////////////////////////////////////////////////////////////////////
698 bool ValidateProperty(CMaterial
* pMaterial
, const std::deque
<string
>& splittedPropertyPathParam
, const SPyWrappedProperty
& value
)
700 std::deque
<string
> splittedPropertyPath
= splittedPropertyPathParam
;
701 std::deque
<string
> splittedPropertyPathSubCategory
= splittedPropertyPathParam
;
702 string categoryName
= splittedPropertyPath
.front();
703 string subCategoryName
= "";
704 string subSubCategoryName
= "";
705 string currentPath
= "";
706 string propertyName
= splittedPropertyPath
.back();
708 string errorMsgInvalidValue
= string("Invalid value for property \"") + propertyName
+ "\"";
709 string errorMsgInvalidDataType
= string("Invalid data type for property \"") + propertyName
+ "\"";
710 string errorMsgInvalidPropertyPath
= string("Invalid property path");
712 const int iMinColorValue
= 0;
713 const int iMaxColorValue
= 255;
715 if (splittedPropertyPathSubCategory
.size() == 3)
717 splittedPropertyPathSubCategory
.pop_back();
718 subCategoryName
= splittedPropertyPathSubCategory
.back();
719 currentPath
= string("") + categoryName
+ "/" + subCategoryName
;
722 subCategoryName
!= "TexType" &&
723 subCategoryName
!= "Filter" &&
724 subCategoryName
!= "IsProjectedTexGen" &&
725 subCategoryName
!= "TexGenType" &&
726 subCategoryName
!= "Wave X" &&
727 subCategoryName
!= "Wave Y" &&
728 subCategoryName
!= "Wave Z" &&
729 subCategoryName
!= "Wave W" &&
730 subCategoryName
!= "Shader1" &&
731 subCategoryName
!= "Shader2" &&
732 subCategoryName
!= "Shader3" &&
733 subCategoryName
!= "Tiling" &&
734 subCategoryName
!= "Rotator" &&
735 subCategoryName
!= "Oscillator" &&
736 subCategoryName
!= "Diffuse" &&
737 subCategoryName
!= "Specular" &&
738 subCategoryName
!= "Bumpmap" &&
739 subCategoryName
!= "Heightmap" &&
740 subCategoryName
!= "Environment" &&
741 subCategoryName
!= "Detail" &&
742 subCategoryName
!= "Opacity" &&
743 subCategoryName
!= "Decal" &&
744 subCategoryName
!= "SubSurface" &&
745 subCategoryName
!= "Custom" &&
746 subCategoryName
!= "[1] Custom"
749 throw std::runtime_error(errorMsgInvalidPropertyPath
+ " (" + currentPath
+ ")");
752 else if (splittedPropertyPathSubCategory
.size() == 4)
754 splittedPropertyPathSubCategory
.pop_back();
755 subCategoryName
= splittedPropertyPathSubCategory
.back();
756 splittedPropertyPathSubCategory
.pop_back();
757 subSubCategoryName
= splittedPropertyPathSubCategory
.back();
758 currentPath
= categoryName
+ "/" + subSubCategoryName
+ "/" + subCategoryName
;
761 subSubCategoryName
!= "Diffuse" &&
762 subSubCategoryName
!= "Specular" &&
763 subSubCategoryName
!= "Bumpmap" &&
764 subSubCategoryName
!= "Heightmap" &&
765 subSubCategoryName
!= "Environment" &&
766 subSubCategoryName
!= "Detail" &&
767 subSubCategoryName
!= "Opacity" &&
768 subSubCategoryName
!= "Decal" &&
769 subSubCategoryName
!= "SubSurface" &&
770 subSubCategoryName
!= "Custom" &&
771 subSubCategoryName
!= "[1] Custom"
774 throw std::runtime_error(errorMsgInvalidPropertyPath
+ " (" + currentPath
+ ")");
776 else if (subCategoryName
!= "Tiling" && subCategoryName
!= "Rotator" && subCategoryName
!= "Oscillator")
778 throw std::runtime_error(errorMsgInvalidPropertyPath
+ " (" + currentPath
+ ")");
783 currentPath
= categoryName
;
787 categoryName
== "Material Settings" ||
788 categoryName
== "Opacity Settings" ||
789 categoryName
== "Lighting Settings" ||
790 categoryName
== "Advanced" ||
791 categoryName
== "Texture Maps" ||
792 categoryName
== "Vertex Deformation" ||
793 categoryName
== "Layer Presets")
795 if (propertyName
== "Opacity" || propertyName
== "AlphaTest" || propertyName
== "Glow Amount")
798 if (value
.type
!= SPyWrappedProperty::eType_Int
)
800 throw std::runtime_error(errorMsgInvalidDataType
);
803 if (value
.property
.intValue
< 0 || value
.property
.intValue
> 100)
805 throw std::runtime_error(errorMsgInvalidValue
);
809 else if (propertyName
== "Glossiness")
812 if (value
.type
!= SPyWrappedProperty::eType_Int
)
814 throw std::runtime_error(errorMsgInvalidDataType
);
817 if (value
.property
.intValue
< iMinColorValue
|| value
.property
.intValue
> iMaxColorValue
)
819 throw std::runtime_error(errorMsgInvalidValue
);
823 else if (propertyName
== "Specular Level" || propertyName
== "Heat Amount")
825 // float: 0.0 < x < 4.0
826 if (value
.type
!= SPyWrappedProperty::eType_Float
)
828 throw std::runtime_error(errorMsgInvalidDataType
);
831 if (value
.property
.floatValue
< 0.0f
|| value
.property
.floatValue
> 4.0f
)
833 throw std::runtime_error(errorMsgInvalidValue
);
837 else if (propertyName
== "Fur Amount" || propertyName
== "Cloak Amount")
839 // float: 0.0 < x < 1.0
840 if (value
.type
!= SPyWrappedProperty::eType_Float
)
842 throw std::runtime_error(errorMsgInvalidDataType
);
845 if (value
.property
.floatValue
< 0.0f
|| value
.property
.floatValue
> 1.0f
)
847 throw std::runtime_error(errorMsgInvalidValue
);
852 propertyName
== "TileU" ||
853 propertyName
== "TileV" ||
854 propertyName
== "OffsetU" ||
855 propertyName
== "OffsetV" ||
856 propertyName
== "RotateU" ||
857 propertyName
== "RotateV" ||
858 propertyName
== "RotateW" ||
859 propertyName
== "Rate" ||
860 propertyName
== "Phase" ||
861 propertyName
== "Amplitude" ||
862 propertyName
== "CenterU" ||
863 propertyName
== "CenterV" ||
864 propertyName
== "RateU" ||
865 propertyName
== "RateV" ||
866 propertyName
== "PhaseU" ||
867 propertyName
== "PhaseV" ||
868 propertyName
== "AmplitudeU" ||
869 propertyName
== "AmplitudeV" ||
870 propertyName
== "Wave Length X" ||
871 propertyName
== "Wave Length Y" ||
872 propertyName
== "Wave Length Z" ||
873 propertyName
== "Wave Length W" ||
874 propertyName
== "Level" ||
875 propertyName
== "Amplitude" ||
876 propertyName
== "Phase" ||
877 propertyName
== "Frequency")
879 // float: 0.0 < x < 100.0
880 if (value
.type
!= SPyWrappedProperty::eType_Float
)
882 throw std::runtime_error(errorMsgInvalidDataType
);
885 if (value
.property
.floatValue
< 0.0f
|| value
.property
.floatValue
> 100.0f
)
887 throw std::runtime_error(errorMsgInvalidValue
);
891 else if (propertyName
== "Diffuse Color" || propertyName
== "Specular Color" || propertyName
== "Emissive Color")
893 // intVector(RGB): 0 < x < 255
894 if (value
.type
!= SPyWrappedProperty::eType_Color
)
896 throw std::runtime_error(errorMsgInvalidDataType
);
899 if (value
.property
.colorValue
.r
< iMinColorValue
|| value
.property
.colorValue
.r
> iMaxColorValue
)
901 throw std::runtime_error(errorMsgInvalidValue
+ " (red)");
903 else if (value
.property
.colorValue
.g
< iMinColorValue
|| value
.property
.colorValue
.g
> iMaxColorValue
)
905 throw std::runtime_error(errorMsgInvalidValue
+ " (green)");
907 else if (value
.property
.colorValue
.b
< iMinColorValue
|| value
.property
.colorValue
.b
> iMaxColorValue
)
909 throw std::runtime_error(errorMsgInvalidValue
+ " (blue)");
914 propertyName
== "Template Material" ||
915 propertyName
== "Link to Material" ||
916 propertyName
== "Surface Type" ||
917 propertyName
== "Diffuse" ||
918 propertyName
== "Specular" ||
919 propertyName
== "Bumpmap" ||
920 propertyName
== "Heightmap" ||
921 propertyName
== "Environment" ||
922 propertyName
== "Detail" ||
923 propertyName
== "Opacity" ||
924 propertyName
== "Decal" ||
925 propertyName
== "SubSurface" ||
926 propertyName
== "Custom" ||
927 propertyName
== "[1] Custom" ||
928 propertyName
== "TexType" ||
929 propertyName
== "Filter" ||
930 propertyName
== "TexGenType" ||
931 propertyName
== "Type" ||
932 propertyName
== "TypeU" ||
933 propertyName
== "TypeV")
936 if (value
.type
!= SPyWrappedProperty::eType_String
)
938 throw std::runtime_error(errorMsgInvalidDataType
);
943 propertyName
== "Additive" ||
944 propertyName
== "Allow layer activation" ||
945 propertyName
== "2 Sided" ||
946 propertyName
== "No Shadow" ||
947 propertyName
== "Use Scattering" ||
948 propertyName
== "Hide After Breaking" ||
949 propertyName
== "Traceable Texture" ||
950 propertyName
== "Propagate Material Settings" ||
951 propertyName
== "Propagate Opacity Settings" ||
952 propertyName
== "Propagate Lighting Settings" ||
953 propertyName
== "Propagate Advanced Settings" ||
954 propertyName
== "Propagate Texture Maps" ||
955 propertyName
== "Propagate Shader Params" ||
956 propertyName
== "Propagate Shader Generation" ||
957 propertyName
== "Propagate Vertex Deformation" ||
958 propertyName
== "Propagate Layer Presets" ||
959 propertyName
== "IsProjectedTexGen" ||
960 propertyName
== "IsTileU" ||
961 propertyName
== "IsTileV" ||
962 propertyName
== "No Draw")
965 if (value
.type
!= SPyWrappedProperty::eType_Bool
)
967 throw std::runtime_error(errorMsgInvalidDataType
);
971 else if (propertyName
== "Shader" || propertyName
== "Shader1" || propertyName
== "Shader2" || propertyName
== "Shader3")
973 // string && valid shader
974 if (value
.type
!= SPyWrappedProperty::eType_String
)
976 throw std::runtime_error(errorMsgInvalidDataType
);
979 const auto& shaderList
= GetIEditorImpl()->GetMaterialManager()->GetShaderList();
980 if (std::find(shaderList
.begin(), shaderList
.end(), value
.stringValue
) != shaderList
.end())
983 else if (propertyName
== "Noise Scale")
985 // FloatVec: undefined < x < undefined
986 if (value
.type
!= SPyWrappedProperty::eType_Vec3
)
988 throw std::runtime_error(errorMsgInvalidDataType
);
993 else if (categoryName
== "Shader Params")
995 DynArray
<SShaderParam
>& shaderParams
= pMaterial
->GetShaderResources().m_ShaderParams
;
996 for (int i
= 0; i
< shaderParams
.size(); i
++)
998 if (propertyName
== ParseUINameFromPublicParamsScript(shaderParams
[i
].m_Script
))
1000 if (shaderParams
[i
].m_Type
== eType_FLOAT
)
1002 // float: valid range (from script)
1003 if (value
.type
!= SPyWrappedProperty::eType_Float
)
1005 throw std::runtime_error(errorMsgInvalidDataType
);
1007 std::map
<string
, float> range
= ParseValidRangeFromPublicParamsScript(shaderParams
[i
].m_Script
);
1008 if (value
.property
.floatValue
< range
["UIMin"] || value
.property
.floatValue
> range
["UIMax"])
1011 errorMsg
.Format("Invalid value for shader param \"%s\" (min: %f, max: %f)", propertyName
, range
["UIMin"], range
["UIMax"]);
1012 throw std::runtime_error(errorMsg
);
1016 else if (shaderParams
[i
].m_Type
== eType_FCOLOR
)
1018 // intVector(RGB): 0 < x < 255
1019 if (value
.type
!= SPyWrappedProperty::eType_Color
)
1021 throw std::runtime_error(errorMsgInvalidDataType
);
1024 if (value
.property
.colorValue
.r
< iMinColorValue
|| value
.property
.colorValue
.r
> iMaxColorValue
)
1026 throw std::runtime_error(errorMsgInvalidValue
+ " (red)");
1028 else if (value
.property
.colorValue
.g
< iMinColorValue
|| value
.property
.colorValue
.g
> iMaxColorValue
)
1030 throw std::runtime_error(errorMsgInvalidValue
+ " (green)");
1032 else if (value
.property
.colorValue
.b
< iMinColorValue
|| value
.property
.colorValue
.b
> iMaxColorValue
)
1034 throw std::runtime_error(errorMsgInvalidValue
+ " (blue)");
1041 else if (categoryName
== "Shader Generation Params")
1043 for (int i
= 0; i
< pMaterial
->GetShaderGenParamsVars()->GetNumVariables(); i
++)
1045 if (propertyName
== pMaterial
->GetShaderGenParamsVars()->GetVariable(i
)->GetHumanName())
1047 if (value
.type
!= SPyWrappedProperty::eType_Bool
)
1049 throw std::runtime_error(errorMsgInvalidDataType
);
1057 throw std::runtime_error(errorMsgInvalidPropertyPath
+ " (" + currentPath
+ ")");
1062 //////////////////////////////////////////////////////////////////////////
1064 SPyWrappedProperty
PyGetProperty(const char* pPathAndMaterialName
, const char* pPathAndPropertyName
)
1066 CMaterial
* pMaterial
= TryLoadingMaterial(pPathAndMaterialName
);
1067 std::deque
<string
> splittedPropertyPath
= PreparePropertyPath(pPathAndPropertyName
);
1068 std::deque
<string
> splittedPropertyPathCategory
= splittedPropertyPath
;
1069 string categoryName
= splittedPropertyPath
.front();
1070 string subCategoryName
= "None";
1071 string subSubCategoryName
= "None";
1072 string propertyName
= splittedPropertyPath
.back();
1073 string errorMsgInvalidPropertyPath
= "Invalid property path.";
1074 SPyWrappedProperty value
;
1076 if (splittedPropertyPathCategory
.size() == 3)
1078 splittedPropertyPathCategory
.pop_back();
1079 subCategoryName
= splittedPropertyPathCategory
.back();
1081 else if (splittedPropertyPathCategory
.size() == 4)
1083 splittedPropertyPathCategory
.pop_back();
1084 subCategoryName
= splittedPropertyPathCategory
.back();
1085 splittedPropertyPathCategory
.pop_back();
1086 subSubCategoryName
= splittedPropertyPathCategory
.back();
1089 // ########## Material Settings ##########
1090 if (categoryName
== "Material Settings")
1092 if (propertyName
== "Template Material")
1094 value
.type
= SPyWrappedProperty::eType_String
;
1095 value
.stringValue
= pMaterial
->GetMatTemplate();
1097 else if (propertyName
== "Shader")
1099 value
.type
= SPyWrappedProperty::eType_String
;
1100 value
.stringValue
= pMaterial
->GetShaderName();
1102 else if (propertyName
== "Surface Type")
1104 value
.type
= SPyWrappedProperty::eType_String
;
1105 value
.stringValue
= pMaterial
->GetSurfaceTypeName();
1106 if (value
.stringValue
.Find("mat_") == 0)
1108 value
.stringValue
.Delete(0, 4);
1113 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid material setting.");
1116 // ########## Opacity Settings ##########
1117 else if (categoryName
== "Opacity Settings")
1119 if (propertyName
== "Opacity")
1121 value
.type
= SPyWrappedProperty::eType_Int
;
1122 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_LMaterial
.m_Opacity
;
1123 value
.property
.intValue
= value
.property
.floatValue
* 100.0f
;
1125 else if (propertyName
== "AlphaTest")
1127 value
.type
= SPyWrappedProperty::eType_Int
;
1128 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_AlphaRef
;
1129 value
.property
.intValue
= value
.property
.floatValue
* 100.0f
;
1131 else if (propertyName
== "Additive")
1133 value
.type
= SPyWrappedProperty::eType_Bool
;
1134 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_ADDITIVE
;
1138 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid opacity setting.");
1141 // ########## Lighting Settings ##########
1142 else if (categoryName
== "Lighting Settings")
1144 if (propertyName
== "Diffuse Color")
1146 value
.type
= SPyWrappedProperty::eType_Color
;
1147 COLORREF col
= CMFCUtils::ColorLinearToGamma(ColorF(
1148 pMaterial
->GetShaderResources().m_LMaterial
.m_Diffuse
.r
,
1149 pMaterial
->GetShaderResources().m_LMaterial
.m_Diffuse
.g
,
1150 pMaterial
->GetShaderResources().m_LMaterial
.m_Diffuse
.b
));
1151 value
.property
.colorValue
.r
= (int)GetRValue(col
);
1152 value
.property
.colorValue
.g
= (int)GetGValue(col
);
1153 value
.property
.colorValue
.b
= (int)GetBValue(col
);
1155 else if (propertyName
== "Specular Color")
1157 value
.type
= SPyWrappedProperty::eType_Color
;
1158 COLORREF col
= CMFCUtils::ColorLinearToGamma(ColorF(
1159 pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.r
/ pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
,
1160 pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.g
/ pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
,
1161 pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.b
/ pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
));
1162 value
.property
.colorValue
.r
= (int)GetRValue(col
);
1163 value
.property
.colorValue
.g
= (int)GetGValue(col
);
1164 value
.property
.colorValue
.b
= (int)GetBValue(col
);
1166 else if (propertyName
== "Glossiness")
1168 value
.type
= SPyWrappedProperty::eType_Int
;
1169 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_LMaterial
.m_Smoothness
;
1170 value
.property
.intValue
= (int)value
.property
.floatValue
;
1172 else if (propertyName
== "Specular Level")
1174 value
.type
= SPyWrappedProperty::eType_Float
;
1175 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
;
1177 else if (propertyName
== "Emissive Color")
1179 value
.type
= SPyWrappedProperty::eType_Color
;
1180 COLORREF col
= CMFCUtils::ColorLinearToGamma(ColorF(
1181 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.r
,
1182 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.g
,
1183 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.b
));
1184 value
.property
.colorValue
.r
= (int)GetRValue(col
);
1185 value
.property
.colorValue
.g
= (int)GetGValue(col
);
1186 value
.property
.colorValue
.b
= (int)GetBValue(col
);
1188 else if (propertyName
== "Emissive Intensity")
1190 value
.type
= SPyWrappedProperty::eType_Float
;
1191 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.a
;
1195 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid lighting setting.");
1198 // ########## Advanced ##########
1199 else if (categoryName
== "Advanced")
1201 if (propertyName
== "Allow layer activation")
1203 value
.type
= SPyWrappedProperty::eType_Bool
;
1204 value
.property
.boolValue
= pMaterial
->LayerActivationAllowed();
1206 else if (propertyName
== "2 Sided")
1208 value
.type
= SPyWrappedProperty::eType_Bool
;
1209 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_2SIDED
;
1211 else if (propertyName
== "No Shadow")
1213 value
.type
= SPyWrappedProperty::eType_Bool
;
1214 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_NOSHADOW
;
1216 else if (propertyName
== "Use Scattering")
1218 value
.type
= SPyWrappedProperty::eType_Bool
;
1219 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_SCATTER
;
1221 else if (propertyName
== "Hide After Breaking")
1223 value
.type
= SPyWrappedProperty::eType_Bool
;
1224 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_HIDEONBREAK
;
1226 else if (propertyName
== "Traceable Texture")
1228 value
.type
= SPyWrappedProperty::eType_Bool
;
1229 value
.property
.boolValue
= pMaterial
->GetFlags() & MTL_FLAG_TRACEABLE_TEXTURE
;
1231 else if (propertyName
== "Fur Amount")
1233 value
.type
= SPyWrappedProperty::eType_Float
;
1234 value
.property
.floatValue
= (float)pMaterial
->GetShaderResources().m_FurAmount
/ 255.0f
;
1236 else if (propertyName
== "Voxel Coverage")
1238 value
.type
= SPyWrappedProperty::eType_Float
;
1239 value
.property
.floatValue
= (float)pMaterial
->GetShaderResources().m_VoxelCoverage
/ 255.0f
;
1241 else if (propertyName
== "Heat Amount")
1243 value
.type
= SPyWrappedProperty::eType_Float
;
1244 value
.property
.floatValue
= ((float)pMaterial
->GetShaderResources().m_HeatAmount
/ 255.0f
) * 4.0f
;
1246 else if (propertyName
== "Cloak Amount")
1248 value
.type
= SPyWrappedProperty::eType_Float
;
1249 value
.property
.floatValue
= (float)pMaterial
->GetShaderResources().m_CloakAmount
/ 255.0f
;
1251 else if (propertyName
== "Link to Material")
1253 value
.type
= SPyWrappedProperty::eType_String
;
1254 value
.stringValue
= pMaterial
->GetMatInfo()->GetMaterialLinkName();
1256 else if (propertyName
== "Propagate Material Settings")
1258 value
.type
= SPyWrappedProperty::eType_Bool
;
1259 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_MATERIAL_SETTINGS
;
1261 else if (propertyName
== "Propagate Opacity Settings")
1263 value
.type
= SPyWrappedProperty::eType_Bool
;
1264 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_OPACITY
;
1266 else if (propertyName
== "Propagate Lighting Settings")
1268 value
.type
= SPyWrappedProperty::eType_Bool
;
1269 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_LIGHTING
;
1271 else if (propertyName
== "Propagate Advanced Settings")
1273 value
.type
= SPyWrappedProperty::eType_Bool
;
1274 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_ADVANCED
;
1276 else if (propertyName
== "Propagate Texture Maps")
1278 value
.type
= SPyWrappedProperty::eType_Bool
;
1279 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_TEXTURES
;
1281 else if (propertyName
== "Propagate Shader Params")
1283 value
.type
= SPyWrappedProperty::eType_Bool
;
1284 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_SHADER_PARAMS
;
1286 else if (propertyName
== "Propagate Shader Generation")
1288 value
.type
= SPyWrappedProperty::eType_Bool
;
1289 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_SHADER_GEN
;
1291 else if (propertyName
== "Propagate Vertex Deformation")
1293 value
.type
= SPyWrappedProperty::eType_Bool
;
1294 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_VERTEX_DEF
;
1296 else if (propertyName
== "Propagate Layer Presets")
1298 value
.type
= SPyWrappedProperty::eType_Bool
;
1299 value
.property
.boolValue
= pMaterial
->GetPropagationFlags() & MTL_PROPAGATE_LAYER_PRESETS
;
1303 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid advanced setting.");
1306 // ########## Texture Maps ##########
1307 else if (categoryName
== "Texture Maps")
1309 // ########## Texture Maps / [name] ##########
1310 if (splittedPropertyPath
.size() == 2)
1312 value
.type
= SPyWrappedProperty::eType_String
;
1313 value
.stringValue
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(propertyName
)].m_Name
.c_str();
1315 // ########## Texture Maps / [TexType | Filter | IsProjectedTexGen | TexGenType ] ##########
1316 else if (splittedPropertyPath
.size() == 3)
1318 SEfResTexture
& currentResTexture
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(subCategoryName
)];
1320 if (propertyName
== "TexType")
1322 value
.type
= SPyWrappedProperty::eType_String
;
1323 value
.stringValue
= TryConvertingETEX_TypeToCString(currentResTexture
.m_Sampler
.m_eTexType
);
1325 else if (propertyName
== "Filter")
1327 value
.type
= SPyWrappedProperty::eType_String
;
1328 value
.stringValue
= TryConvertingTexFilterToCString(currentResTexture
.m_Filter
);
1330 else if (propertyName
== "IsProjectedTexGen")
1332 value
.type
= SPyWrappedProperty::eType_Bool
;
1333 value
.property
.boolValue
= currentResTexture
.AddModificator()->m_bTexGenProjected
;
1335 else if (propertyName
== "TexGenType")
1337 value
.type
= SPyWrappedProperty::eType_String
;
1338 value
.stringValue
= TryConvertingETexGenTypeToCString(currentResTexture
.AddModificator()->m_eTGType
);
1342 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1345 // ########## Texture Maps / [Tiling | Rotator | Oscillator] ##########
1346 else if (splittedPropertyPath
.size() == 4)
1348 SEfResTexture
& currentResTexture
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(subSubCategoryName
)];
1350 if (subCategoryName
== "Tiling")
1352 if (propertyName
== "IsTileU")
1354 value
.type
= SPyWrappedProperty::eType_Bool
;
1355 value
.property
.boolValue
= currentResTexture
.m_bUTile
;
1357 else if (propertyName
== "IsTileV")
1359 value
.type
= SPyWrappedProperty::eType_Bool
;
1360 value
.property
.boolValue
= currentResTexture
.m_bVTile
;
1362 else if (propertyName
== "TileU")
1364 value
.type
= SPyWrappedProperty::eType_Float
;
1365 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_Tiling
[0];
1367 else if (propertyName
== "TileV")
1369 value
.type
= SPyWrappedProperty::eType_Float
;
1370 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_Tiling
[1];
1372 else if (propertyName
== "OffsetU")
1374 value
.type
= SPyWrappedProperty::eType_Float
;
1375 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_Offs
[0];
1377 else if (propertyName
== "OffsetV")
1379 value
.type
= SPyWrappedProperty::eType_Float
;
1380 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_Offs
[1];
1382 else if (propertyName
== "RotateU")
1384 value
.type
= SPyWrappedProperty::eType_Float
;
1385 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_Rot
[0]);
1387 else if (propertyName
== "RotateV")
1389 value
.type
= SPyWrappedProperty::eType_Float
;
1390 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_Rot
[1]);
1392 else if (propertyName
== "RotateW")
1394 value
.type
= SPyWrappedProperty::eType_Float
;
1395 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_Rot
[2]);
1399 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1402 else if (subCategoryName
== "Rotator")
1404 if (propertyName
== "Type")
1406 value
.type
= SPyWrappedProperty::eType_String
;
1407 value
.stringValue
= TryConvertingETexModRotateTypeToCString(currentResTexture
.AddModificator()->m_eRotType
);
1409 else if (propertyName
== "Rate")
1411 value
.type
= SPyWrappedProperty::eType_Float
;
1412 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_RotOscRate
[2]);
1414 else if (propertyName
== "Phase")
1416 value
.type
= SPyWrappedProperty::eType_Float
;
1417 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_RotOscPhase
[2]);
1419 else if (propertyName
== "Amplitude")
1421 value
.type
= SPyWrappedProperty::eType_Float
;
1422 value
.property
.floatValue
= Word2Degr(currentResTexture
.AddModificator()->m_RotOscAmplitude
[2]);
1424 else if (propertyName
== "CenterU")
1426 value
.type
= SPyWrappedProperty::eType_Float
;
1427 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_RotOscCenter
[0];
1429 else if (propertyName
== "CenterV")
1431 value
.type
= SPyWrappedProperty::eType_Float
;
1432 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_RotOscCenter
[1];
1436 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1439 else if (subCategoryName
== "Oscillator")
1441 if (propertyName
== "TypeU")
1443 value
.type
= SPyWrappedProperty::eType_String
;
1444 value
.stringValue
= TryConvertingETexModMoveTypeToCString(currentResTexture
.AddModificator()->m_eMoveType
[0]);
1446 else if (propertyName
== "TypeV")
1448 value
.type
= SPyWrappedProperty::eType_String
;
1449 value
.stringValue
= TryConvertingETexModMoveTypeToCString(currentResTexture
.AddModificator()->m_eMoveType
[1]);
1451 else if (propertyName
== "RateU")
1453 value
.type
= SPyWrappedProperty::eType_Float
;
1454 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscRate
[0];
1456 else if (propertyName
== "RateV")
1458 value
.type
= SPyWrappedProperty::eType_Float
;
1459 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscRate
[1];
1461 else if (propertyName
== "PhaseU")
1463 value
.type
= SPyWrappedProperty::eType_Float
;
1464 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscPhase
[0];
1466 else if (propertyName
== "PhaseV")
1468 value
.type
= SPyWrappedProperty::eType_Float
;
1469 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscPhase
[1];
1471 else if (propertyName
== "AmplitudeU")
1473 value
.type
= SPyWrappedProperty::eType_Float
;
1474 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscAmplitude
[0];
1476 else if (propertyName
== "AmplitudeV")
1478 value
.type
= SPyWrappedProperty::eType_Float
;
1479 value
.property
.floatValue
= currentResTexture
.AddModificator()->m_OscAmplitude
[1];
1483 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1488 throw std::runtime_error(string("\"") + subCategoryName
+ "\" is an invalid sub category.");
1493 throw std::runtime_error(errorMsgInvalidPropertyPath
);
1496 // ########## Shader Params ##########
1497 else if (categoryName
== "Shader Params")
1499 DynArray
<SShaderParam
>& shaderParams
= pMaterial
->GetShaderResources().m_ShaderParams
;
1500 bool isPropertyFound(false);
1502 for (int i
= 0; i
< shaderParams
.size(); i
++)
1504 if (propertyName
== ParseUINameFromPublicParamsScript(shaderParams
[i
].m_Script
))
1506 if (shaderParams
[i
].m_Type
== eType_FLOAT
)
1508 value
.type
= SPyWrappedProperty::eType_Float
;
1509 value
.property
.floatValue
= shaderParams
[i
].m_Value
.m_Float
;
1510 isPropertyFound
= true;
1513 else if (shaderParams
[i
].m_Type
== eType_FCOLOR
)
1515 value
.type
= SPyWrappedProperty::eType_Color
;
1516 COLORREF col
= CMFCUtils::ColorLinearToGamma(ColorF(
1517 shaderParams
[i
].m_Value
.m_Vector
[0],
1518 shaderParams
[i
].m_Value
.m_Vector
[1],
1519 shaderParams
[i
].m_Value
.m_Vector
[2]));
1520 value
.property
.colorValue
.r
= (int)GetRValue(col
);
1521 value
.property
.colorValue
.g
= (int)GetGValue(col
);
1522 value
.property
.colorValue
.b
= (int)GetBValue(col
);
1523 isPropertyFound
= true;
1529 if (!isPropertyFound
)
1531 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid shader param.");
1534 // ########## Shader Generation Params ##########
1535 else if (categoryName
== "Shader Generation Params")
1537 value
.type
= SPyWrappedProperty::eType_Bool
;
1538 bool isPropertyFound(false);
1539 for (int i
= 0; i
< pMaterial
->GetShaderGenParamsVars()->GetNumVariables(); i
++)
1541 if (propertyName
== pMaterial
->GetShaderGenParamsVars()->GetVariable(i
)->GetHumanName())
1543 isPropertyFound
= true;
1544 pMaterial
->GetShaderGenParamsVars()->GetVariable(i
)->Get(value
.property
.boolValue
);
1549 if (!isPropertyFound
)
1551 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid shader generation param.");
1554 // ########## Vertex Deformation ##########
1555 else if (categoryName
== "Vertex Deformation")
1557 // ########## Vertex Deformation / [ Type | Wave Length X | Wave Length Y | Wave Length Z | Wave Length W | Noise Scale ] ##########
1558 if (splittedPropertyPath
.size() == 2)
1560 if (propertyName
== "Type")
1562 value
.type
= SPyWrappedProperty::eType_String
;
1563 value
.stringValue
= TryConvertingEDeformTypeToCString(pMaterial
->GetShaderResources().m_DeformInfo
.m_eType
);
1565 else if (propertyName
== "Wave Length X")
1567 value
.type
= SPyWrappedProperty::eType_Float
;
1568 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerX
;
1570 else if (propertyName
== "Wave Length Y")
1572 value
.type
= SPyWrappedProperty::eType_Float
;
1573 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerY
;
1575 else if (propertyName
== "Wave Length Z")
1577 value
.type
= SPyWrappedProperty::eType_Float
;
1578 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerZ
;
1580 else if (propertyName
== "Wave Length W")
1582 value
.type
= SPyWrappedProperty::eType_Float
;
1583 value
.property
.floatValue
= pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerW
;
1585 else if (propertyName
== "Noise Scale")
1587 value
.type
= SPyWrappedProperty::eType_Vec3
;
1588 value
.property
.vecValue
.x
= pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[0];
1589 value
.property
.vecValue
.y
= pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[1];
1590 value
.property
.vecValue
.z
= pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[2];
1594 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1597 // ########## Vertex Deformation / [ Wave X | Wave Y | Wave Z | Wave W ] ##########
1598 else if (splittedPropertyPath
.size() == 3)
1600 if (subCategoryName
== "Wave X" || subCategoryName
== "Wave Y" || subCategoryName
== "Wave Z" || subCategoryName
== "Wave W")
1602 SWaveForm2 currentWaveForm
;
1603 if (subCategoryName
== "Wave X")
1605 currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveX
;
1607 else if (subCategoryName
== "Wave Y")
1609 currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveY
;
1611 else if (subCategoryName
== "Wave Z")
1613 currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveZ
;
1615 else if (subCategoryName
== "Wave W")
1617 currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveW
;
1620 if (propertyName
== "Type")
1622 value
.type
= SPyWrappedProperty::eType_String
;
1623 value
.stringValue
= TryConvertingEWaveFormToCString(currentWaveForm
.m_eWFType
);
1625 else if (propertyName
== "Level")
1627 value
.type
= SPyWrappedProperty::eType_Float
;
1628 value
.property
.floatValue
= currentWaveForm
.m_Level
;
1630 else if (propertyName
== "Amplitude")
1632 value
.type
= SPyWrappedProperty::eType_Float
;
1633 value
.property
.floatValue
= currentWaveForm
.m_Amp
;
1635 else if (propertyName
== "Phase")
1637 value
.type
= SPyWrappedProperty::eType_Float
;
1638 value
.property
.floatValue
= currentWaveForm
.m_Phase
;
1640 else if (propertyName
== "Frequency")
1642 value
.type
= SPyWrappedProperty::eType_Float
;
1643 value
.property
.floatValue
= currentWaveForm
.m_Freq
;
1647 throw std::runtime_error(string("\"") + propertyName
+ "\" is an invalid property.");
1652 throw std::runtime_error(string("\"") + categoryName
+ "\" is an invalid category.");
1657 throw std::runtime_error(errorMsgInvalidPropertyPath
);
1660 // ########## Layer Presets ##########
1661 else if (categoryName
== "Layer Presets")
1663 // names are "Shader1", "Shader2" and "Shader3", bacause all have the name "Shader" in material editor
1664 if (splittedPropertyPath
.size() == 2)
1666 value
.type
= SPyWrappedProperty::eType_String
;
1668 int shaderNumber
= -1;
1669 if (propertyName
== "Shader1")
1673 else if (propertyName
== "Shader2")
1677 else if (propertyName
== "Shader3")
1683 throw std::runtime_error("Invalid shader.");
1686 value
.stringValue
= pMaterial
->GetMtlLayerResources()[shaderNumber
].m_shaderName
;
1688 else if (splittedPropertyPath
.size() == 3)
1690 if (propertyName
== "No Draw")
1692 value
.type
= SPyWrappedProperty::eType_Bool
;
1694 int shaderNumber
= -1;
1695 if (subCategoryName
== "Shader1")
1699 else if (subCategoryName
== "Shader2")
1703 else if (subCategoryName
== "Shader3")
1709 throw std::runtime_error("Invalid shader.");
1711 value
.property
.boolValue
= pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
& MTL_LAYER_USAGE_NODRAW
;
1716 throw std::runtime_error(errorMsgInvalidPropertyPath
);
1721 throw std::runtime_error(errorMsgInvalidPropertyPath
);
1727 void PySetProperty(const char* pPathAndMaterialName
, const char* pPathAndPropertyName
, const SPyWrappedProperty
& value
)
1729 CMaterial
* pMaterial
= TryLoadingMaterial(pPathAndMaterialName
);
1730 std::deque
<string
> splittedPropertyPath
= PreparePropertyPath(pPathAndPropertyName
);
1731 std::deque
<string
> splittedPropertyPathCategory
= splittedPropertyPath
;
1732 string categoryName
= splittedPropertyPath
.front();
1733 string subCategoryName
= "None";
1734 string subSubCategoryName
= "None";
1735 string propertyName
= splittedPropertyPath
.back();
1736 string errorMsgInvalidPropertyPath
= "Invalid property path.";
1738 if (!ValidateProperty(pMaterial
, splittedPropertyPath
, value
))
1740 throw std::runtime_error("Invalid property.");
1743 string undoMsg
= "Set Material Property";
1744 CUndo
undo(undoMsg
);
1745 pMaterial
->RecordUndo(undoMsg
, true);
1747 if (splittedPropertyPathCategory
.size() == 3)
1749 splittedPropertyPathCategory
.pop_back();
1750 subCategoryName
= splittedPropertyPathCategory
.back();
1752 else if (splittedPropertyPathCategory
.size() == 4)
1754 splittedPropertyPathCategory
.pop_back();
1755 subCategoryName
= splittedPropertyPathCategory
.back();
1756 splittedPropertyPathCategory
.pop_back();
1757 subSubCategoryName
= splittedPropertyPathCategory
.back();
1760 // ########## Material Settings ##########
1761 if (categoryName
== "Material Settings")
1763 if (propertyName
== "Template Material")
1765 pMaterial
->SetMatTemplate(value
.stringValue
);
1767 else if (propertyName
== "Shader")
1769 pMaterial
->SetShaderName(value
.stringValue
);
1771 else if (propertyName
== "Surface Type")
1773 bool isSurfaceExist(false);
1774 string realSurfacename
= "";
1775 ISurfaceTypeEnumerator
* pSurfaceTypeEnum
= gEnv
->p3DEngine
->GetMaterialManager()->GetSurfaceTypeManager()->GetEnumerator();
1776 if (pSurfaceTypeEnum
)
1778 for (ISurfaceType
* pSurfaceType
= pSurfaceTypeEnum
->GetFirst(); pSurfaceType
; pSurfaceType
= pSurfaceTypeEnum
->GetNext())
1780 string surfaceName
= pSurfaceType
->GetName();
1781 realSurfacename
= surfaceName
;
1782 if (surfaceName
.Left(4) == "mat_")
1784 surfaceName
.Delete(0, 4);
1786 if (surfaceName
== value
.stringValue
)
1788 isSurfaceExist
= true;
1789 pMaterial
->SetSurfaceTypeName(realSurfacename
);
1793 if (!isSurfaceExist
)
1795 throw std::runtime_error("Invalid surface type name.");
1800 throw std::runtime_error("Surface Type Enumerator corrupted.");
1804 // ########## Opacity Settings ##########
1805 else if (categoryName
== "Opacity Settings")
1807 if (propertyName
== "Opacity")
1809 pMaterial
->GetShaderResources().m_LMaterial
.m_Opacity
= static_cast<float>(value
.property
.intValue
) / 100.0f
;
1811 else if (propertyName
== "AlphaTest")
1813 pMaterial
->GetShaderResources().m_AlphaRef
= static_cast<float>(value
.property
.intValue
) / 100.0f
;
1815 else if (propertyName
== "Additive")
1817 SetMaterialFlag(pMaterial
, MTL_FLAG_ADDITIVE
, value
.property
.boolValue
);
1820 // ########## Lighting Settings ##########
1821 else if (categoryName
== "Lighting Settings")
1823 if (propertyName
== "Diffuse Color")
1825 ColorB
color(value
.property
.colorValue
.r
, value
.property
.colorValue
.g
, value
.property
.colorValue
.b
);
1826 pMaterial
->GetShaderResources().m_LMaterial
.m_Diffuse
= CMFCUtils::ColorGammaToLinear(RGB(color
.r
, color
.g
, color
.b
));
1828 else if (propertyName
== "Specular Color")
1830 ColorB
color(value
.property
.colorValue
.r
, value
.property
.colorValue
.g
, value
.property
.colorValue
.b
);
1831 ColorF colorFloat
= CMFCUtils::ColorGammaToLinear(RGB(color
.r
, color
.g
, color
.b
));
1832 colorFloat
.a
= pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
;
1833 colorFloat
.r
*= colorFloat
.a
;
1834 colorFloat
.g
*= colorFloat
.a
;
1835 colorFloat
.b
*= colorFloat
.a
;
1836 pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
= colorFloat
;
1838 else if (propertyName
== "Glossiness")
1840 pMaterial
->GetShaderResources().m_LMaterial
.m_Smoothness
= static_cast<float>(value
.property
.intValue
);
1842 else if (propertyName
== "Specular Level")
1844 float tempFloat
= pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
.a
;
1845 float tempFloat2
= value
.property
.floatValue
;
1847 ColorF colorFloat
= pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
;
1848 colorFloat
.a
= value
.property
.floatValue
;
1849 colorFloat
.r
*= colorFloat
.a
;
1850 colorFloat
.g
*= colorFloat
.a
;
1851 colorFloat
.b
*= colorFloat
.a
;
1852 colorFloat
.a
= 1.0f
;
1853 pMaterial
->GetShaderResources().m_LMaterial
.m_Specular
= colorFloat
;
1856 else if (propertyName
== "Emissive Color")
1858 ColorB
color(value
.property
.colorValue
.r
, value
.property
.colorValue
.g
, value
.property
.colorValue
.b
);
1859 float emissiveIntensity
= pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.a
;
1860 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
= CMFCUtils::ColorGammaToLinear(RGB(color
.r
, color
.g
, color
.b
));
1861 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.a
= emissiveIntensity
;
1863 else if (propertyName
== "Emissive Intensity")
1865 pMaterial
->GetShaderResources().m_LMaterial
.m_Emittance
.a
= value
.property
.floatValue
;
1868 // ########## Advanced ##########
1869 else if (categoryName
== "Advanced")
1871 if (propertyName
== "Allow layer activation")
1873 pMaterial
->SetLayerActivation(value
.property
.boolValue
);
1875 else if (propertyName
== "2 Sided")
1877 SetMaterialFlag(pMaterial
, MTL_FLAG_2SIDED
, value
.property
.boolValue
);
1879 else if (propertyName
== "No Shadow")
1881 SetMaterialFlag(pMaterial
, MTL_FLAG_NOSHADOW
, value
.property
.boolValue
);
1883 else if (propertyName
== "Use Scattering")
1885 SetMaterialFlag(pMaterial
, MTL_FLAG_SCATTER
, value
.property
.boolValue
);
1887 else if (propertyName
== "Hide After Breaking")
1889 SetMaterialFlag(pMaterial
, MTL_FLAG_HIDEONBREAK
, value
.property
.boolValue
);
1891 else if (propertyName
== "Traceable Texture")
1893 SetMaterialFlag(pMaterial
, MTL_FLAG_TRACEABLE_TEXTURE
, value
.property
.boolValue
);
1895 else if (propertyName
== "Fur Amount")
1897 pMaterial
->GetShaderResources().m_FurAmount
= static_cast<uint8
>(value
.property
.floatValue
* 255.0f
);
1899 else if (propertyName
== "Voxel Coverage")
1901 pMaterial
->GetShaderResources().m_VoxelCoverage
= static_cast<uint8
>(value
.property
.floatValue
* 255.0f
);
1903 else if (propertyName
== "Heat Amount")
1905 pMaterial
->GetShaderResources().m_HeatAmount
= static_cast<uint8
>((value
.property
.floatValue
/ 4.0f
) * 255.0f
);
1907 else if (propertyName
== "Cloak Amount")
1909 pMaterial
->GetShaderResources().m_CloakAmount
= static_cast<uint8
>((value
.property
.floatValue
* 255.0f
));
1911 else if (propertyName
== "Link to Material")
1913 pMaterial
->GetMatInfo()->SetMaterialLinkName(value
.stringValue
);
1915 else if (propertyName
== "Propagate Material Settings")
1917 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_MATERIAL_SETTINGS
, value
.property
.boolValue
);
1919 else if (propertyName
== "Propagate Opacity Settings")
1921 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_OPACITY
, value
.property
.boolValue
);
1923 else if (propertyName
== "Propagate Lighting Settings")
1925 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_LIGHTING
, value
.property
.boolValue
);
1927 else if (propertyName
== "Propagate Advanced Settings")
1929 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_ADVANCED
, value
.property
.boolValue
);
1931 else if (propertyName
== "Propagate Texture Maps")
1933 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_TEXTURES
, value
.property
.boolValue
);
1935 else if (propertyName
== "Propagate Shader Params")
1937 if (value
.property
.boolValue
== true)
1939 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_MATERIAL_SETTINGS
, true);
1941 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_SHADER_PARAMS
, value
.property
.boolValue
);
1943 else if (propertyName
== "Propagate Shader Generation")
1945 if (value
.property
.boolValue
== true)
1947 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_MATERIAL_SETTINGS
, true);
1949 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_SHADER_GEN
, value
.property
.boolValue
);
1951 else if (propertyName
== "Propagate Vertex Deformation")
1953 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_VERTEX_DEF
, value
.property
.boolValue
);
1955 else if (propertyName
== "Propagate Layer Presets")
1957 SetPropagationFlag(pMaterial
, MTL_PROPAGATE_LAYER_PRESETS
, value
.property
.boolValue
);
1960 // ########## Texture Maps ##########
1961 else if (categoryName
== "Texture Maps")
1963 // ########## Texture Maps / [name] ##########
1964 if (splittedPropertyPath
.size() == 2)
1966 SEfResTexture
& currentResTexture
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(propertyName
)];
1967 currentResTexture
.m_Name
= value
.stringValue
;
1969 // ########## Texture Maps / [TexType | Filter | IsProjectedTexGen | TexGenType ] ##########
1970 else if (splittedPropertyPath
.size() == 3)
1972 SEfResTexture
& currentResTexture
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(subCategoryName
)];
1974 if (propertyName
== "TexType")
1976 currentResTexture
.m_Sampler
.m_eTexType
= TryConvertingCStringToETEX_Type(value
.stringValue
);
1978 else if (propertyName
== "Filter")
1980 currentResTexture
.m_Filter
= TryConvertingCStringToTexFilter(value
.stringValue
);
1982 else if (propertyName
== "IsProjectedTexGen")
1984 currentResTexture
.AddModificator()->m_bTexGenProjected
= value
.property
.boolValue
;
1986 else if (propertyName
== "TexGenType")
1988 currentResTexture
.AddModificator()->m_eTGType
= TryConvertingCStringToETexGenType(value
.stringValue
);
1991 // ########## Texture Maps / [Tiling | Rotator | Oscillator] ##########
1992 else if (splittedPropertyPath
.size() == 4)
1994 SEfResTexture
& currentResTexture
= pMaterial
->GetShaderResources().m_Textures
[TryConvertingCStringToEEfResTextures(subSubCategoryName
)];
1996 if (subCategoryName
== "Tiling")
1998 if (propertyName
== "IsTileU")
2000 currentResTexture
.m_bUTile
= value
.property
.boolValue
;
2002 else if (propertyName
== "IsTileV")
2004 currentResTexture
.m_bVTile
= value
.property
.boolValue
;
2006 else if (propertyName
== "TileU")
2008 currentResTexture
.AddModificator()->m_Tiling
[0] = value
.property
.floatValue
;
2010 else if (propertyName
== "TileV")
2012 currentResTexture
.AddModificator()->m_Tiling
[1] = value
.property
.floatValue
;
2014 else if (propertyName
== "OffsetU")
2016 currentResTexture
.AddModificator()->m_Offs
[0] = value
.property
.floatValue
;
2018 else if (propertyName
== "OffsetV")
2020 currentResTexture
.AddModificator()->m_Offs
[1] = value
.property
.floatValue
;
2022 else if (propertyName
== "RotateU")
2024 currentResTexture
.AddModificator()->m_Rot
[0] = Degr2Word(value
.property
.floatValue
);
2026 else if (propertyName
== "RotateV")
2028 currentResTexture
.AddModificator()->m_Rot
[1] = Degr2Word(value
.property
.floatValue
);
2030 else if (propertyName
== "RotateW")
2032 currentResTexture
.AddModificator()->m_Rot
[2] = Degr2Word(value
.property
.floatValue
);
2035 else if (subCategoryName
== "Rotator")
2037 if (propertyName
== "Type")
2039 currentResTexture
.AddModificator()->m_eRotType
= TryConvertingCStringToETexModRotateType(value
.stringValue
);
2041 else if (propertyName
== "Rate")
2043 currentResTexture
.AddModificator()->m_RotOscRate
[2] = Degr2Word(value
.property
.floatValue
);
2045 else if (propertyName
== "Phase")
2047 currentResTexture
.AddModificator()->m_RotOscPhase
[2] = Degr2Word(value
.property
.floatValue
);
2049 else if (propertyName
== "Amplitude")
2051 currentResTexture
.AddModificator()->m_RotOscAmplitude
[2] = Degr2Word(value
.property
.floatValue
);
2053 else if (propertyName
== "CenterU")
2055 currentResTexture
.AddModificator()->m_RotOscCenter
[0] = value
.property
.floatValue
;
2057 else if (propertyName
== "CenterV")
2059 currentResTexture
.AddModificator()->m_RotOscCenter
[1] = value
.property
.floatValue
;
2062 else if (subCategoryName
== "Oscillator")
2064 if (propertyName
== "TypeU")
2066 currentResTexture
.AddModificator()->m_eMoveType
[0] = TryConvertingCStringToETexModMoveType(value
.stringValue
);
2068 else if (propertyName
== "TypeV")
2070 currentResTexture
.AddModificator()->m_eMoveType
[1] = TryConvertingCStringToETexModMoveType(value
.stringValue
);
2072 else if (propertyName
== "RateU")
2074 currentResTexture
.AddModificator()->m_OscRate
[0] = value
.property
.floatValue
;
2076 else if (propertyName
== "RateV")
2078 currentResTexture
.AddModificator()->m_OscRate
[1] = value
.property
.floatValue
;
2080 else if (propertyName
== "PhaseU")
2082 currentResTexture
.AddModificator()->m_OscPhase
[0] = value
.property
.floatValue
;
2084 else if (propertyName
== "PhaseV")
2086 currentResTexture
.AddModificator()->m_OscPhase
[1] = value
.property
.floatValue
;
2088 else if (propertyName
== "AmplitudeU")
2090 currentResTexture
.AddModificator()->m_OscAmplitude
[0] = value
.property
.floatValue
;
2092 else if (propertyName
== "AmplitudeV")
2094 currentResTexture
.AddModificator()->m_OscAmplitude
[1] = value
.property
.floatValue
;
2099 // ########## Shader Params ##########
2100 else if (categoryName
== "Shader Params")
2102 DynArray
<SShaderParam
>& shaderParams
= pMaterial
->GetShaderResources().m_ShaderParams
;
2104 for (int i
= 0; i
< shaderParams
.size(); i
++)
2106 if (propertyName
== ParseUINameFromPublicParamsScript(shaderParams
[i
].m_Script
))
2108 if (shaderParams
[i
].m_Type
== eType_FLOAT
)
2110 shaderParams
[i
].m_Value
.m_Float
= value
.property
.floatValue
;
2113 else if (shaderParams
[i
].m_Type
== eType_FCOLOR
)
2115 ColorF colorLinear
= CMFCUtils::ColorGammaToLinear(
2117 (uint8
)value
.property
.colorValue
.r
,
2118 (uint8
)value
.property
.colorValue
.g
,
2119 (uint8
)value
.property
.colorValue
.b
2122 shaderParams
[i
].m_Value
.m_Vector
[0] = colorLinear
.r
;
2123 shaderParams
[i
].m_Value
.m_Vector
[1] = colorLinear
.g
;
2124 shaderParams
[i
].m_Value
.m_Vector
[2] = colorLinear
.b
;
2129 throw std::runtime_error("Invalid data type (Shader Params)");
2134 // ########## Shader Generation Params ##########
2135 else if (categoryName
== "Shader Generation Params")
2137 for (int i
= 0; i
< pMaterial
->GetShaderGenParamsVars()->GetNumVariables(); i
++)
2139 if (propertyName
== pMaterial
->GetShaderGenParamsVars()->GetVariable(i
)->GetHumanName())
2141 CVarBlock
* shaderGenBlock
= pMaterial
->GetShaderGenParamsVars();
2142 shaderGenBlock
->GetVariable(i
)->Set(value
.property
.boolValue
);
2143 pMaterial
->SetShaderGenParamsVars(shaderGenBlock
);
2148 // ########## Vertex Deformation ##########
2149 else if (categoryName
== "Vertex Deformation")
2151 // ########## Vertex Deformation / [ Type | Wave Length X | Wave Length Y | Wave Length Z | Wave Length W | Noise Scale ] ##########
2152 if (splittedPropertyPath
.size() == 2)
2154 if (propertyName
== "Type")
2156 pMaterial
->GetShaderResources().m_DeformInfo
.m_eType
= TryConvertingCStringToEDeformType(value
.stringValue
);
2158 else if (propertyName
== "Wave Length X")
2160 pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerX
= value
.property
.floatValue
;
2162 else if (propertyName
== "Wave Length Y")
2164 pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerY
= value
.property
.floatValue
;
2166 else if (propertyName
== "Wave Length Z")
2168 pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerZ
= value
.property
.floatValue
;
2170 else if (propertyName
== "Wave Length W")
2172 pMaterial
->GetShaderResources().m_DeformInfo
.m_fDividerW
= value
.property
.floatValue
;
2174 else if (propertyName
== "Noise Scale")
2176 pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[0] = value
.property
.vecValue
.x
;
2177 pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[1] = value
.property
.vecValue
.y
;
2178 pMaterial
->GetShaderResources().m_DeformInfo
.m_vNoiseScale
[2] = value
.property
.vecValue
.z
;
2181 // ########## Vertex Deformation / [ Wave X | Wave Y | Wave Z | Wave W ] ##########
2182 else if (splittedPropertyPath
.size() == 3)
2184 if (subCategoryName
== "Wave X")
2186 SWaveForm2
& currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveX
;
2188 if (propertyName
== "Type")
2190 currentWaveForm
.m_eWFType
= TryConvertingCStringToEWaveForm(value
.stringValue
);
2192 else if (propertyName
== "Level")
2194 currentWaveForm
.m_Level
= value
.property
.floatValue
;
2196 else if (propertyName
== "Amplitude")
2198 currentWaveForm
.m_Amp
= value
.property
.floatValue
;
2200 else if (propertyName
== "Phase")
2202 currentWaveForm
.m_Phase
= value
.property
.floatValue
;
2204 else if (propertyName
== "Frequency")
2206 currentWaveForm
.m_Freq
= value
.property
.floatValue
;
2209 else if (subCategoryName
== "Wave Y")
2211 SWaveForm2
& currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveY
;
2213 if (propertyName
== "Type")
2215 currentWaveForm
.m_eWFType
= TryConvertingCStringToEWaveForm(value
.stringValue
);
2217 else if (propertyName
== "Level")
2219 currentWaveForm
.m_Level
= value
.property
.floatValue
;
2221 else if (propertyName
== "Amplitude")
2223 currentWaveForm
.m_Amp
= value
.property
.floatValue
;
2225 else if (propertyName
== "Phase")
2227 currentWaveForm
.m_Phase
= value
.property
.floatValue
;
2229 else if (propertyName
== "Frequency")
2231 currentWaveForm
.m_Freq
= value
.property
.floatValue
;
2234 else if (subCategoryName
== "Wave Z")
2236 SWaveForm2
& currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveZ
;
2238 if (propertyName
== "Type")
2240 currentWaveForm
.m_eWFType
= TryConvertingCStringToEWaveForm(value
.stringValue
);
2242 else if (propertyName
== "Level")
2244 currentWaveForm
.m_Level
= value
.property
.floatValue
;
2246 else if (propertyName
== "Amplitude")
2248 currentWaveForm
.m_Amp
= value
.property
.floatValue
;
2250 else if (propertyName
== "Phase")
2252 currentWaveForm
.m_Phase
= value
.property
.floatValue
;
2254 else if (propertyName
== "Frequency")
2256 currentWaveForm
.m_Freq
= value
.property
.floatValue
;
2259 else if (subCategoryName
== "Wave W")
2261 SWaveForm2
& currentWaveForm
= pMaterial
->GetShaderResources().m_DeformInfo
.m_WaveW
;
2263 if (propertyName
== "Type")
2265 currentWaveForm
.m_eWFType
= TryConvertingCStringToEWaveForm(value
.stringValue
);
2267 else if (propertyName
== "Level")
2269 currentWaveForm
.m_Level
= value
.property
.floatValue
;
2271 else if (propertyName
== "Amplitude")
2273 currentWaveForm
.m_Amp
= value
.property
.floatValue
;
2275 else if (propertyName
== "Phase")
2277 currentWaveForm
.m_Phase
= value
.property
.floatValue
;
2279 else if (propertyName
== "Frequency")
2281 currentWaveForm
.m_Freq
= value
.property
.floatValue
;
2286 // ########## Layer Presets ##########
2287 else if (categoryName
== "Layer Presets")
2289 // names are "Shader1", "Shader2" and "Shader3", bacause all have the name "Shader" in material editor
2290 if (splittedPropertyPath
.size() == 2)
2292 int shaderNumber
= -1;
2293 if (propertyName
== "Shader1")
2297 else if (propertyName
== "Shader2")
2301 else if (propertyName
== "Shader3")
2306 pMaterial
->GetMtlLayerResources()[shaderNumber
].m_shaderName
= value
.stringValue
;
2308 else if (splittedPropertyPath
.size() == 3)
2310 if (propertyName
== "No Draw")
2312 int shaderNumber
= -1;
2313 if (subCategoryName
== "Shader1")
2317 else if (subCategoryName
== "Shader2")
2321 else if (subCategoryName
== "Shader3")
2326 if (pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
& MTL_LAYER_USAGE_NODRAW
&& value
.property
.boolValue
== false)
2328 pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
= pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
- MTL_LAYER_USAGE_NODRAW
;
2330 else if (!(pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
& MTL_LAYER_USAGE_NODRAW
) && value
.property
.boolValue
== true)
2332 pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
= pMaterial
->GetMtlLayerResources()[shaderNumber
].m_nFlags
| MTL_LAYER_USAGE_NODRAW
;
2338 pMaterial
->Update();
2340 GetIEditorImpl()->GetMaterialManager()->OnUpdateProperties(pMaterial
);
2344 DECLARE_PYTHON_MODULE(material
);
2346 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialCreate
, material
, create
,
2347 "Creates a material.",
2348 "material.create()");
2349 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialCreateMulti
, material
, create_multi
,
2350 "Creates a multi-material.",
2351 "material.create_multi()");
2352 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialConvertToMulti
, material
, convert_to_multi
,
2353 "Converts the selected material to a multi-material.",
2354 "material.convert_to_multi()");
2355 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialDuplicateCurrent
, material
, duplicate_current
,
2356 "Duplicates the current material.",
2357 "material.duplicate_current()");
2358 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialMergeSelection
, material
, merge_selection
,
2359 "Merges the selected materials.",
2360 "material.merge_selection()");
2361 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialDeleteCurrent
, material
, delete_current
,
2362 "Deletes the current material.",
2363 "material.delete_current()");
2364 REGISTER_PYTHON_COMMAND(PyCreateTerrainLayer
, material
, create_terrain_layer
, "");
2366 REGISTER_EDITOR_AND_SCRIPT_COMMAND(PyMaterialAssignCurrentToSelection
, material
, assign_current_to_selection
,
2367 CCommandDescription("Assigns the current material to the selection."))
2368 REGISTER_EDITOR_UI_COMMAND_DESC(material
, assign_current_to_selection
, "Assign Current", "", "icons:MaterialEditor/Material_Editor_Assign_To_Object.ico", false)
2369 REGISTER_COMMAND_REMAPPING(ui_action
, actionMaterial_Assign_Current
, material
, assign_current_to_selection
)
2371 REGISTER_EDITOR_AND_SCRIPT_COMMAND(PyMaterialResetSelection
, material
, reset_selection
,
2372 CCommandDescription("Resets the materials of the selection."))
2373 REGISTER_EDITOR_UI_COMMAND_DESC(material
, reset_selection
, "Reset to Default", "", "icons:MaterialEditor/Material_Editor_Reset_Material.ico", false)
2374 REGISTER_COMMAND_REMAPPING(ui_action
, actionMaterial_Reset_to_Default
, material
, reset_selection
)
2376 REGISTER_EDITOR_AND_SCRIPT_COMMAND(PyMaterialSetCurrentFromObject
, material
, set_current_from_object
,
2377 CCommandDescription("Sets the current material to the material of a selected object."))
2378 REGISTER_EDITOR_UI_COMMAND_DESC(material
, set_current_from_object
, "Get from Selected", "", "icons:MaterialEditor/Material_Editor_Pick_From_Object.ico", false)
2379 REGISTER_COMMAND_REMAPPING(ui_action
, actionMaterial_Get_from_Selected
, material
, set_current_from_object
)
2381 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyMaterialSelectObjectsWithCurrent
, material
, select_objects_with_current
,
2382 "Selects the objects which have the current material.",
2383 "material.select_objects_with_current()");
2384 REGISTER_PYTHON_COMMAND_WITH_EXAMPLE(PyGetSubMaterial
, material
, get_submaterial
,
2385 "Gets sub materials of an material.",
2386 "material.get_submaterial()");
2387 REGISTER_ONLY_PYTHON_COMMAND_WITH_EXAMPLE(PyGetProperty
, material
, get_property
,
2388 "Gets a property of a material.",
2389 "material.get_property(str materialPath/materialName, str propertyPath/propertyName)");
2390 REGISTER_ONLY_PYTHON_COMMAND_WITH_EXAMPLE(PySetProperty
, material
, set_property
,
2391 "Sets a property of a material.",
2392 "material.set_property(str materialPath/materialName, str propertyPath/propertyName, [ str | (int, int, int) | (float, float, float) | int | float | bool ] value)");