Leaderboard
Popular Content
Showing content with the highest reputation on 03/13/2021 in all areas
-
Hi @israeldavid, hi @srek, I think that is a fun topic 😄 . But I also think you underestimate a bit the size of our solar system ^^ Neptune, the last planet in our system (sorry, Pluto 😞 ), has a radius of about 25,000 km but is about 4.5 billion kilometers away from the sun. So its not hard to imagine that when you work with real data, that you won't see much except the sun and maybee a planet when you are close enough. So you will need some sort of scaling when you want to show the whole solar system. Srek's approach of animating stuff more or less manually is probably much more production focused, but I thought I'd give it a go with a Python generator. It took me surprisingly only about 90 lines of code to do a somewhat working solar system. You can find the code and a scene file below. Please keep in mind that I mostly did this as a "fun thing", so it will likely not be exactly what you want, but maybe you can still borrow bits from it (for example to do the expressions Srek talked about). My approach is deliberately data driven, since this is what I thought to be fun 😉 A little animation done with the generator, the little blue pixel is earth. The solar system is at 1% distance scale of the real solar system, so 1km is 10m in this system. solar_system.mp4 Cheers, Ferdinand The code: """Summary Attributes: ORBITAL_SYSTEM (TYPE): Description """ import c4d import math INVERSE_EARTH_PERIOD = 1. / 365. # The solar system as a hierarchical data structure. Distances and radii are # measured in kilometers, orbital periods are measured in (earth) days. You # can extend the system easily by just adding satellites (technically you # could also let the sun orbit something). The code below is however setup in # such fashion that you can only have one root in the system, i.e., you cannot # have two primaries in the data structure at level zero. ORBITAL_SYSTEM = { "Sun": { # The name of the primary "radius": 696340, # The radius of the primary "distance": 0, # The distance to its primary "color": c4d.Vector(1, .75, 0), # The viewport color of the primary "period": 0, # The orbital period of the primary "satellites": { # The satellites of the primary "Mercury": { "radius": 2439.7, "distance": 57.91E6, # i.e., 57.91 million kilometers "color": c4d.Vector(.55, .55, .55), "period": 88, "satellites": {}, }, "Venus": { "radius": 6051.8, "distance": 108.2E6, "color": c4d.Vector(.9, .9, .9), "period": 225, "satellites": {}, }, "Earth": { "radius": 6371, "distance": 148.55E6, "color": c4d.Vector(.1, .5, .9), "period": 365, "satellites": { "Moon": { "radius": 1737.1, "distance": 384400, "color": c4d.Vector(.3, .3, .3), "period": 27, "satellites": {} }, }, }, "Mars": { "radius": 3389.5, "distance": 240.16E6, "color": c4d.Vector(.85, .35, .1), "period": 687, "satellites": {}, }, "Jupiter": { "radius": 69911, "distance": 778.5E6, "color": c4d.Vector(.85, .7, .1), "period": 4380, "satellites": {}, }, "Saturn": { "radius": 58232, "distance": 1489.6E6, "color": c4d.Vector(.55, .4, .25), "period": 10585, "satellites": {}, }, "Uranus": { "radius": 25362, "distance": 2871E6, "color": c4d.Vector(.65, .85, .95), "period": 30660, "satellites": {}, }, "Neptune": { "radius": 24622, "distance": 4495E6, "color": c4d.Vector(.05, .45, .65), "period": 60225, "satellites": {}, }, }, }, } TWO_PI = math.pi * 2. def build_system(name, data, settings): """Builds a system from a fragment of an ORBITAL_SYSTEM data structure. This function builds recursively all the sub-systems of a system. Args: name (str): The name of the primary. data (dict): Its data dictionary taken from ORBITAL_SYSTEM. settings (dict): The user data parameters. Returns: c4d.BaseObject: The system fragment. """ # The primary as a sphere object. primary = c4d.BaseList2D(c4d.Osphere) primary.SetName("body") primary.MakeTag(c4d.Tphong) # Write its node data. combined_scale = settings["global_scale"] * settings["distance_scale"] xpos = data["distance"] * combined_scale primary[c4d.PRIM_SPHERE_SUB] = 32 primary[c4d.PRIM_SPHERE_RAD] = data["radius"] * settings["global_scale"] primary[c4d.ID_BASEOBJECT_REL_POSITION, c4d.VECTOR_X] = xpos primary[c4d.ID_BASEOBJECT_USECOLOR] = 2 primary[c4d.ID_BASEOBJECT_COLOR] = data["color"] # And build its satellites. for satellite_name, satellite_data in data["satellites"].items(): satellite = build_system(satellite_name, satellite_data, settings) satellite.InsertUnder(primary) # A null so that we can easily animate the orbit arround its primary. root = c4d.BaseList2D(c4d.Onull) root.SetName(name) primary.InsertUnder(root) # The current document time. t = doc.GetTime().Get() # Animation period of of that primary in relation to earth period. p = data["period"] * settings["orbit_duration"] * INVERSE_EARTH_PERIOD # Bails if the object has no period. if p == 0.0: return root # The rotational value as the fraction of period remainder of the # document time. We then have to multiply by 2π since Cinema handles # roatation in radians. theta = TWO_PI * (t % p / p) # Set the heading of the null. root[c4d.ID_BASEOBJECT_REL_ROTATION, c4d.VECTOR_X] = theta return root def main(): """Entry point for Cinema 4D to evaluate the Python generator object. """ settings = { # Out input data is in real world units, we have to scale this # a bit down. "global_scale": op[c4d.ID_USERDATA, 1], # Just our solar system alone is fricking huge, so we propbably want # to scale down distances a bit, so that we can actually see # something. "distance_scale": op[c4d.ID_USERDATA, 2], # The time in seconds on year takes, i.e., one full earth orbit. "orbit_duration": op[c4d.ID_USERDATA, 4], } # The root element. root_name = list(ORBITAL_SYSTEM.keys())[0] root_data = ORBITAL_SYSTEM[root_name] # Build the system. root = build_system(root_name, root_data, settings) # This is only needed for when the user collapses the Python generator via # CSTO, so that we get then a nice hierarchy. system = c4d.BaseList2D(c4d.Onull) system.SetName(op.GetName()) root.InsertUnder(system) return system solar_system.c4d1 point