Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Python access to plLayer and ImageLibMod textures. #1360

Merged
merged 21 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion Scripts/Python/plasma/Plasma.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

from __future__ import annotations
from PlasmaConstants import *
from typing import Callable, Optional, Tuple, Union
from typing import Callable, Iterable, Optional, Tuple, Union

def PtAcceptInviteInGame(friendName,inviteKey):
"""Sends a VaultTask to the server to perform the invite"""
Expand Down Expand Up @@ -306,6 +306,14 @@ def PtFileExists(filename):
"""Returns true if the specified file exists"""
pass

def PtFindImage(name: str) -> Iterable[ptImage]:
"""Find an already loaded image by name"""
...

def PtFindLayer(name: str, age: str = "", page: str = "") -> Optional[ptLayer]:
"""Find a layer by name"""
...

def PtFindSceneobject(name,ageName):
"""This will try to find a sceneobject based on its name and what age its in
- it will return a ptSceneObject if found- if not found then a NameError exception will happen"""
Expand Down Expand Up @@ -5271,6 +5279,24 @@ def saveAsJPEG(self,filename,quality=75):
"""Saves this image to disk as a JPEG file"""
pass

class ptImageLibMod:
"""Plasma ImageLibraryModifier class"""
def __init__(self,imlkey):
"""None"""
pass

def getImage(imageName):
"""Returns the named image, if present"""
pass

def getImages():
"""Returns a tuple of ptImages"""
pass

def getNames():
"""Returns a tuple of the image names"""
pass

class ptInputInterface:
"""Plasma input interface class"""
def __init__(self):
Expand Down Expand Up @@ -5391,6 +5417,20 @@ def writeKeyMap(self):
"""Forces write of the keymap file"""
pass

class ptLayer:
"""Plasma Layer class"""
def __init__(self,layerKey):
"""None"""
pass

def getTexture(self) -> ptImage:
"""Returns the image texture of the layer"""
...

def setTexture(self, image: ptImage) -> None:
"""Sets the texture of the layer"""
...

class ptMarkerMgr:
"""Marker manager accessor class"""
def __init__(self):
Expand Down Expand Up @@ -6066,6 +6106,10 @@ def getPythonMods(self):
"""Returns list of ptKeys of the python modifiers attached to this sceneobject"""
pass

def getImageLibMods(self):
"""Returns list of ptKeys of the image library modifiers attached to this sceneobject"""
pass

def getResponderState(self):
"""Return the responder state (if we are a responder)"""
pass
Expand Down
12 changes: 12 additions & 0 deletions Scripts/Python/plasma/PlasmaTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,18 @@ def __setvalue__(self,value):
self.shader = ptGrassShader(value)
self.value = self.shader

# a Layer attribute
class ptAttribLayer(ptAttribute):
def __init__(self,id,name=None):
ptAttribute.__init__(self,id,name)
self.value = None
self.layer = None
def getdef(self):
return (self.id, self.name, 25)
def __setvalue__(self,value):
self.layer = ptLayer(value)
self.value = self.layer


#
# ptModifier - class for creating a Plasma modifier, such as a responder
Expand Down
21 changes: 21 additions & 0 deletions Scripts/Python/stupStartUp.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@
launch start up sequence
"""

import random

from Plasma import *
from PlasmaTypes import *

# define the attributes that will be entered in max
Camera = ptAttribSceneobject(1, "Camera")
BGObj = ptAttribSceneobject(2, "Background Object")
BGLayer = ptAttribLayer(3, "Background Image Layer")

#====================================

Expand Down Expand Up @@ -104,3 +108,20 @@ def OnServerInitComplete(self):
PtShowDialog("GUIDialog04b")
else:
PtShowDialog("GUIDialog06")

self.randomizeBackground()


###########################
def randomizeBackground(self):
if not BGObj.sceneobject or not BGLayer.layer:
PtDebugPrint("stupStartUp: Missing ptAttribs for randomized backgrounds. Leaving default...")
return

# Get the first available ImageLibModifier on our Background SceneObject
if ilm := next(iter(BGObj.sceneobject.getImageLibMods()), None):
# Choose a random image from the available images
bgChoice = random.choice(ilm.getImages())
# Update the Background Layer's texture to our chosen image
BGLayer.layer.setTexture(bgChoice)
PtDebugPrint("stupStartUp: Background has been randomized.")
12 changes: 12 additions & 0 deletions Sources/MaxPlugin/MaxComponent/plAutoUIBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,18 @@ void plAutoUIBase::AddPickGrassComponentButton(int16_t id, const ST::string& scr
fParams.push_back(param);
}

void plAutoUIBase::AddPickLayerButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set<ST::string> vstates)
{
ST::string scriptNameNew = !scriptName.empty() ? scriptName : IMakeScriptName(name);

fDesc->AddParam(id, ST2M(scriptNameNew), TYPE_REFTARG, 0, 0,
p_end,
p_end);
plAutoUIParam* param = new plPickMaterialButtonParam(id, name);
param->SetVisInfo(vid, std::move(vstates));
fParams.push_back(param);
}

INT_PTR CALLBACK plAutoUIBase::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
plAutoUIBase *pthis = nullptr;
Expand Down
1 change: 1 addition & 0 deletions Sources/MaxPlugin/MaxComponent/plAutoUIBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class plAutoUIBase

void AddDropDownList(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set<ST::string> vstates, std::vector<ST::string> options);
void AddPickGrassComponentButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set<ST::string> vstates);
void AddPickLayerButton(int16_t id, const ST::string& scriptName, const ST::string& name, int vid, std::unordered_set<ST::string> vstates);

void CreateAutoRollup(IParamBlock2 *pb);
void DestroyAutoRollup();
Expand Down
1 change: 1 addition & 0 deletions Sources/MaxPlugin/MaxComponent/plAutoUIParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class plAutoUIParam
kTypeClusterComponent,
kTypeMaterialAnimation,
kTypeGrassComponent,
kTypeLayer
};

plAutoUIParam(ParamID id, ST::string name);
Expand Down
16 changes: 16 additions & 0 deletions Sources/MaxPlugin/MaxComponent/plPythonFileComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#include "plAvatar/plSwimRegion.h"
#include "plSurface/plGrassShaderMod.h"
#include "plGrassComponent.h"
#include "plSurface/plLayer.h"

#include "plMessageBox/hsMessageBox.h"

Expand Down Expand Up @@ -990,6 +991,21 @@ bool plPythonFileComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg)
}
}
break;
case plAutoUIParam::kTypeLayer:
{
int numKeys = param->GetCount(pb);
for (int i = 0; i < numKeys; i++)
{
plKey key = param->GetKey(pb, i);
// make sure we got a key and that it is a plLayer
if (key && plLayer::ConvertNoRef(key->GetObjectPtr()))
{
pyParam.SetToLayer(key);
mod->AddParameter(pyParam);
}
}
}
break;

}
}
Expand Down
11 changes: 10 additions & 1 deletion Sources/MaxPlugin/MaxMain/plPythonMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ enum ParamTypes
kTypeSwimCurrentInterface, // 21
kTypeClusterComponent, // 22
kTypeMaterialAnimation, // 23
kTypeGrassComponent, // 24
kTypeGrassComponent, // 24
kTypeLayer, // 25
};

bool IGetTupleInt(PyObject *tuple, int pos, int& val)
Expand Down Expand Up @@ -451,6 +452,9 @@ bool plPythonMgr::IQueryPythonFile(const ST::string& fileName)
case kTypeGrassComponent:
IAddGrassComponent(autoUI, ret, paramName, paramID, ddlParamID, vec);
break;
case kTypeLayer:
IAddLayerComponent(autoUI, ret, paramName, paramID, ddlParamID, vec);
break;
}
}
}
Expand Down Expand Up @@ -624,6 +628,11 @@ void plPythonMgr::IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple,
autoUI->AddPickGrassComponentButton(id, {}, paramName, vid, std::move(vstates));
}

void plPythonMgr::IAddLayerComponent(plAutoUIBlock* autoUI, PyObject* objTuple, const ST::string& paramName, int id, int vid, std::unordered_set<ST::string> vstates)
{
autoUI->AddPickLayerButton(id, {}, paramName, vid, std::move(vstates));
}

void plPythonMgr::LoadPythonFiles()
{
plFileName clientPath = plMaxConfig::GetClientPath(false, true);
Expand Down
1 change: 1 addition & 0 deletions Sources/MaxPlugin/MaxMain/plPythonMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class plPythonMgr
void IAddClusterComponent(plAutoUIBlock *autoUI, PyObject *tuple, const ST::string& paramName, int id, int vid, std::unordered_set<ST::string> vstates);
void IAddMaterialAnimation(plAutoUIBlock *autoUI, PyObject *tuple, const ST::string& paramName, int id, int vid, std::unordered_set<ST::string> vstates);
void IAddGrassComponent(plAutoUIBlock *autoUI, PyObject *objTuple, const ST::string& paramName, int id, int vid, std::unordered_set<ST::string> vstates);
void IAddLayerComponent(plAutoUIBlock *autoUI, PyObject *objTuple, const ST::string& paramName, int id, int vid, std::unordered_set<ST::string> vstates);

public:
static plPythonMgr& Instance();
Expand Down
7 changes: 7 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ set(pfPython_SOURCES
pyGUIPopUpMenu.cpp
pyGUISkin.cpp
pyImage.cpp
pyImageLibMod.cpp
pyJournalBook.cpp
pyKey.cpp
pyKeyMap.cpp
pyLayer.cpp
pyMarkerMgr.cpp
pyMatrix44.cpp
pyMoviePlayer.cpp
Expand Down Expand Up @@ -142,9 +144,11 @@ set(pfPython_HEADERS
pyGUIPopUpMenu.h
pyGUISkin.h
pyImage.h
pyImageLibMod.h
pyJournalBook.h
pyKey.h
pyKeyMap.h
pyLayer.h
pyMarkerMgr.h
pyMatrix44.h
pyMoviePlayer.h
Expand Down Expand Up @@ -229,9 +233,11 @@ set(pfPython_GLUE
pyGUIPopUpMenuGlue.cpp
pyGUISkinGlue.cpp
pyImageGlue.cpp
pyImageLibModGlue.cpp
pyJournalBookGlue.cpp
pyKeyGlue.cpp
pyKeyMapGlue.cpp
pyLayerGlue.cpp
pyMarkerMgrGlue.cpp
pyMatrix44Glue.cpp
pyMoviePlayerGlue.cpp
Expand Down Expand Up @@ -294,6 +300,7 @@ target_link_libraries(
plGImage
plGLight
plInputCore
plSurface
plModifier
plNetClient
plNetClientComm
Expand Down
5 changes: 5 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#include "pyJournalBook.h"

#include "pyKeyMap.h"
#include "pyImageLibMod.h"
#include "pyLayer.h"
#include "pyStream.h"

#include "pyMoviePlayer.h"
Expand Down Expand Up @@ -1037,6 +1039,7 @@ void PythonInterface::AddPlasmaMethods(PyObject* m)
pyGUIDialog::AddPlasmaMethods(m);
pyImage::AddPlasmaMethods(m);
pyJournalBook::AddPlasmaMethods(m);
pyLayer::AddPlasmaMethods(m);
pySDLModifier::AddPlasmaMethods(m);
pySpawnPointInfo::AddPlasmaMethods(m);
}
Expand Down Expand Up @@ -1079,8 +1082,10 @@ void PythonInterface::AddPlasmaClasses(PyObject* plasmaMod)
pyDniInfoSource::AddPlasmaClasses(plasmaMod);
pyDynamicText::AddPlasmaClasses(plasmaMod);
pyImage::AddPlasmaClasses(plasmaMod);
pyImageLibMod::AddPlasmaClasses(plasmaMod);
pyJournalBook::AddPlasmaClasses(plasmaMod);
pyKeyMap::AddPlasmaClasses(plasmaMod);
pyLayer::AddPlasmaClasses(plasmaMod);
pyMarkerMgr::AddPlasmaClasses(plasmaMod);
pyMoviePlayer::AddPlasmaClasses(plasmaMod);
pyNetLinkingMgr::AddPlasmaClasses(plasmaMod);
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/FeatureLib/pfPython/plPythonFileMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ void plPythonFileMod::AddTarget(plSceneObject* sobj)
case plPythonParameter::kClusterComponentList:
case plPythonParameter::kMaterialAnimation:
case plPythonParameter::kGrassShaderComponent:
case plPythonParameter::kLayer:
if (parameter.fObjectKey) {
// create pyKey for the object
value = pyKey::New(parameter.fObjectKey);
Expand Down
12 changes: 12 additions & 0 deletions Sources/Plasma/FeatureLib/pfPython/plPythonParameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef struct plPythonParameter
kClusterComponentList,
kMaterialAnimation,
kGrassShaderComponent,
kLayer,
kNone
};

Expand Down Expand Up @@ -204,6 +205,9 @@ typedef struct plPythonParameter
case kGrassShaderComponent:
SetToGrassShaderComponent(other.fObjectKey);
break;
case kLayer:
SetToLayer(other.fObjectKey);
break;
}
return *this;
}
Expand Down Expand Up @@ -347,6 +351,12 @@ typedef struct plPythonParameter
fValueType = kGrassShaderComponent;
fObjectKey = std::move(key);
}
void SetToLayer(plKey key)
{
SetToNone();
fValueType = kLayer;
fObjectKey = std::move(key);
}

// read and write routines for export and reading in at runtime
void Read(hsStream *stream, hsResMgr* mgr)
Expand Down Expand Up @@ -404,6 +414,7 @@ typedef struct plPythonParameter
case kClusterComponentList:
case kMaterialAnimation:
case kGrassShaderComponent:
case kLayer:
fObjectKey = mgr->ReadKey(stream);
break;
}
Expand Down Expand Up @@ -455,6 +466,7 @@ typedef struct plPythonParameter
case kClusterComponentList:
case kMaterialAnimation:
case kGrassShaderComponent:
case kLayer:
mgr->WriteKey(stream, fObjectKey);
break;

Expand Down
Loading
Loading