From 5baca5c49385b7dd1b663602e0f052b6c226a73e Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 16 Jul 2015 00:01:38 -0400 Subject: [PATCH] WaveSet environment maps --- korman/exporter/material.py | 43 ++++++++++++++++------------ korman/properties/modifiers/water.py | 26 ++++++++++++++++- korman/ui/modifiers/water.py | 2 ++ 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/korman/exporter/material.py b/korman/exporter/material.py index d63a797..67ddb10 100644 --- a/korman/exporter/material.py +++ b/korman/exporter/material.py @@ -386,37 +386,31 @@ class MaterialConverter: pl_env = plDynamicCamMap else: pl_env = plDynamicEnvMap - pl_env = self._export_dynamic_env(bo, hsgmat, layer, texture, pl_env) + pl_env = self.export_dynamic_env(bo, hsgmat, layer, texture, pl_env) else: # We should really export a CubicEnvMap here, but we have a good setup for DynamicEnvMaps # that create themselves when the explorer links in, so really... who cares about CEMs? self._exporter().report.warn("IMAGE EnvironmentMaps are not supported. '{}' will not be exported!".format(layer.key.name)) pl_env = None layer.state.shadeFlags |= hsGMatState.kShadeEnvironMap - layer.texture = pl_env + layer.texture = pl_env.key - def _export_dynamic_env(self, bo, hsgmat, layer, texture, pl_class): + def export_dynamic_env(self, bo, hsgmat, layer, texture, pl_class): # To protect the user from themselves, let's check to make sure that a DEM/DCM matching this # viewpoint object has not already been exported... bl_env = texture.environment_map viewpt = bl_env.viewpoint_object + if viewpt is None: + viewpt = bo name = "{}_DynEnvMap".format(viewpt.name) - pl_env = self._mgr.find_key(pl_class, bl=bo, name=name) + pl_env = self._mgr.find_object(pl_class, bl=bo, name=name) if pl_env is not None: print(" EnvMap for viewpoint {} already exported... NOTE: Your settings here will be overridden by the previous object!".format(viewpt.name)) - pl_env_obj = pl_env.object - if isinstance(pl_env_obj, plDynamicCamMap): - pl_env_obj.addTargetNode(self._mgr.find_key(plSceneObject, bl=bo)) - pl_env_obj.addMatLayer(layer.key) + if isinstance(pl_env, plDynamicCamMap): + pl_env.addTargetNode(self._mgr.find_key(plSceneObject, bl=bo)) + pl_env.addMatLayer(layer.key) return pl_env - # It matters not whether or not the viewpoint object is a Plasma Object, it is exported as at - # least a SceneObject and CoordInterface so that we can touch it... - # NOTE: that harvest_actor makes sure everyone alread knows we're going to have a CI - root = self._mgr.find_create_key(plSceneObject, bl=bo, name=viewpt.name) - self._exporter()._export_coordinate_interface(root.object, bl=bo, name=viewpt.name) - # FIXME: DynamicCamMap Camera - # Ensure POT oRes = bl_env.resolution eRes = helpers.ensure_power_of_two(oRes) @@ -429,7 +423,6 @@ class MaterialConverter: pl_env.yon = bl_env.clip_end pl_env.refreshRate = 0.01 if bl_env.source == "ANIMATED" else 0.0 pl_env.incCharacters = True - pl_env.rootNode = root # FIXME: DCM camera # Perhaps the DEM/DCM fog should be separately configurable at some point? pl_fog = bpy.context.scene.world.plasma_fni @@ -439,6 +432,13 @@ class MaterialConverter: if isinstance(pl_env, plDynamicCamMap): faces = (pl_env,) + # It matters not whether or not the viewpoint object is a Plasma Object, it is exported as at + # least a SceneObject and CoordInterface so that we can touch it... + # NOTE: that harvest_actor makes sure everyone alread knows we're going to have a CI + root = self._mgr.find_create_key(plSceneObject, bl=viewpt) + pl_env.rootNode = root # FIXME: DCM camera + # FIXME: DynamicCamMap Camera + pl_env.addTargetNode(self._mgr.find_key(plSceneObject, bl=bo)) pl_env.addMatLayer(layer.key) @@ -458,8 +458,13 @@ class MaterialConverter: else: faces = pl_env.faces + (pl_env,) - layer.UVWSrc = plLayerInterface.kUVWReflect - layer.state.miscFlags |= hsGMatState.kMiscUseRefractionXform + # DEMs can do just a position vector. We actually prefer this because the WaveSet exporter + # will probably want to steal it for diabolical purposes... + pl_env.position = hsVector3(*viewpt.location) + + if layer is not None: + layer.UVWSrc = plLayerInterface.kUVWReflect + layer.state.miscFlags |= hsGMatState.kMiscUseRefractionXform # Because we might be working with a multi-faced env map. It's even worse than have two faces... for i in faces: @@ -475,7 +480,7 @@ class MaterialConverter: i.viewportBottom = eRes i.ZDepth = 24 - return pl_env.key + return pl_env def _export_texture_type_image(self, bo, hsgmat, layer, slot): """Exports a Blender ImageTexture to a plLayer""" diff --git a/korman/properties/modifiers/water.py b/korman/properties/modifiers/water.py index 04ceb4f..826f665 100644 --- a/korman/properties/modifiers/water.py +++ b/korman/properties/modifiers/water.py @@ -33,6 +33,12 @@ class PlasmaWaterModifier(PlasmaModifierProperties, bpy.types.PropertyGroup): wind_speed = FloatProperty(name="Wind Speed", description="Magnitude of the wind", default=1.0) + envmap_name = StringProperty(name="EnvMap", + description="Texture defining an environment map for this water object") + envmap_radius = FloatProperty(name="Environment Sphere Radius", + description="How far away the first object you want to see is", + min=5.0, max=10000.0, + default=500.0) specular_tint = FloatVectorProperty(name="Specular Tint", subtype="COLOR", @@ -100,11 +106,29 @@ class PlasmaWaterModifier(PlasmaModifierProperties, bpy.types.PropertyGroup): state.rippleScale = self.ripple_scale state.waterHeight = bo.location[2] state.windDir = wind_dir - state.specVector = hsVector3(self.noise / 100, self.specular_start, self.specular_end) + state.specVector = hsVector3(self.noise / 100.0, self.specular_start, self.specular_end) state.specularTint = hsColorRGBA(*self.specular_tint, alpha=self.specular_alpha) state.waterOffset = hsVector3(self.zero_opacity * -1.0, self.zero_reflection * -1.0, self.zero_wave * -1.0) state.depthFalloff = hsVector3(self.depth_opacity, self.depth_reflection, self.depth_wave) + # Environment Map + if self.envmap_name: + texture = bpy.data.textures.get(self.envmap_name, None) + if texture is None: + raise ExportError("{}: Texture '{}' not found".format(self.display_name, self.envmap_name)) + if texture.type != "ENVIRONMENT_MAP": + raise ExportError("{}: Texture '{}' is not an ENVIRONMENT MAP".format(self.display_name, self.envmap_name)) + + # maybe, just maybe, we're absuing our privledges? + dem = exporter.mesh.material.export_dynamic_env(bo, None, None, texture, plDynamicEnvMap) + waveset.envMap = dem.key + state.envCenter = dem.position + state.envRefresh = dem.refreshRate + else: + state.envCenter = hsVector3(*bo.location) + state.envRefresh = 0.0 + state.envRadius = self.envmap_radius + # These are either unused, set from somewhere else at runtime, or hardcoded state.waterTint = hsColorRGBA(1.0, 1.0, 1.0, 1.0) state.maxColor = hsColorRGBA(1.0, 1.0, 1.0, 1.0) diff --git a/korman/ui/modifiers/water.py b/korman/ui/modifiers/water.py index 918edca..886e99f 100644 --- a/korman/ui/modifiers/water.py +++ b/korman/ui/modifiers/water.py @@ -17,9 +17,11 @@ import bpy def water_basic(modifier, layout, context): layout.prop_search(modifier, "wind_object_name", bpy.data, "objects") + layout.prop_search(modifier, "envmap_name", bpy.data, "textures") row = layout.row() row.prop(modifier, "wind_speed") + row.prop(modifier, "envmap_radius") layout.separator() split = layout.split()